Section 7/101 menit

7. Kapan Tidak Menggunakan Macro

7. Kapan Tidak Menggunakan Macro

Skenario 1: Logic Sederhana yang Bisa Ditulis Langsung

Jika sesuatu bisa diselesaikan dengan beberapa baris kode biasa, macro justru menambah kompleksitas.

swift
// ❌ JANGAN buat macro untuk ini — berlebihan
@AddOne
var count: Int = 5
// Lebih baik langsung:
var count: Int = 5 + 1

Skenario 2: Kebutuhan Runtime Behavior

Macro tidak bisa menggantikan logika yang perlu berjalan saat runtime.

swift
// ❌ Macro TIDAK bisa melakukan ini — runtime decision
@FetchFromAPI  // tidak bisa — API call terjadi saat runtime, bukan compile time
var userData: User

Skenario 3: Tim Kecil Tanpa Kapasitas Maintenance

Macro menambah dependency (swift-syntax) dan membutuhkan pemahaman mendalam tentang AST. Jika tim tidak siap, technical debt bisa menumpuk.

swift
// Pertimbangkan: apakah timmu siap maintain ini?
// swift-syntax sering berubah API-nya setiap versi Swift toolchain
// Setiap upgrade Xcode bisa break macro implementation

Skenario 4: Protocol + Default Implementation Cukup

Jika protocol dengan default implementation bisa melakukan hal yang sama, gunakan itu — lebih mudah dipahami dan di-debug.

swift
// ❌ JANGAN buat macro untuk ini
@AutoLoggable
class MyService { ... }

// ✓ Lebih baik: protocol dengan default implementation
protocol Loggable {
    var logger: Logger { get }
    func log(_ message: String)
}

extension Loggable {
    var logger: Logger { Logger(subsystem: "app", category: String(describing: type(of: self))) }
    func log(_ message: String) { logger.debug("\(message)") }
}

class MyService: Loggable { ... }

Skenario 5: Debugging adalah Prioritas

Macro membuat kode yang "tidak terlihat" — expanded code ada di tempat tersembunyi. Jika kamu sering perlu step-through debugging di bagian tertentu, pertimbangkan untuk tidak menggunakan macro di sana.

swift
// Jika kamu sering debug logika ini, macro menyulitkan:
@ComplexBusinessLogic  // ← kamu tidak bisa set breakpoint di dalam expansion-nya dengan mudah
func processPayment() { ... }