# Factory Pattern

### Apa Itu Factory Pattern?

Factory Pattern pada dasarnya adalah cara untuk **membuat objek tanpa harus mengetahui secara detail bagaimana objek tersebut dibuat**. Bayangkan seperti ini:

* Anda tidak perlu tahu cara membuat mobil dari nol
* Anda hanya perlu pergi ke dealer dan mengatakan "saya mau mobil"
* Dealer (factory) akan membuatkan mobil untuk Anda

Dalam pemrograman, Factory Pattern melakukan hal yang sama: menyediakan fungsi khusus (factory function) yang akan membuat objek untuk kita.

### Contoh Analogi Dunia Nyata

#### Tanpa Factory Pattern:

```go
// Kita harus tahu cara membuat setiap objek secara manual
func main() {
    // Harus tahu detail cara membuat mobil
    car := Car{model: "Toyota", year: 2023}
    
    // Harus tahu detail cara membuat motor
    bike := Bike{type: "Sport", cc: 150}
}
```

#### Dengan Factory Pattern:

```go
// Kita cukup panggil factory function
func main() {
    // Tidak perlu tahu detail pembuatan
    car, _ := NewVehicle("car")
    bike, _ := NewVehicle("bike")
}
```

### Konsep Inti Factory Pattern di Go

Di Go, Factory Pattern memiliki 3 konsep penting:

#### 1. Interface (Kontrak)

```go
type Vehicle interface {
    Move() string
}
```

Ini adalah "kontrak" yang menjamin semua kendaraan punya method `Move()`.

#### 2. Implementasi Konkret

```go
type Car struct{}
func (c Car) Move() string { return "Mobil berjalan" }

type Bike struct{}
func (b Bike) Move() string { return "Motor berjalan" }
```

Ini adalah implementasi spesifik dari interface.

#### 3. Factory Function (Pabrik)

```go
func NewVehicle(tipe string) (Vehicle, error) {
    switch tipe {
    case "car":
        return Car{}, nil
    case "bike":
        return Bike{}, nil
    default:
        return nil, fmt.Errorf("Tipe kendaraan tidak dikenal")
    }
}
```

Ini adalah "pabrik" yang membuat objek sesuai permintaan.

### Mengapa Ini Berguna?

#### 1. Enkapsulasi Logika Pembuatan

```go
// Tanpa Factory
func createCar() Car {
    // Logika kompleks untuk membuat mobil
    // Bisa jadi 100 baris kode
    return Car{...}
}

// Dengan Factory
car, _ := NewVehicle("car") // Satu baris saja
```

#### 2. Fleksibilitas dalam Mengganti Implementasi

```go
// Kita bisa ganti implementasi Car tanpa mengubah kode client
type ElectricCar struct{}
func (e ElectricCar) Move() string { return "Mobil listrik berjalan" }

// Cukup ubah di factory
func NewVehicle(tipe string) (Vehicle, error) {
    switch tipe {
    case "car":
        return ElectricCar{}, nil // Ganti implementasi di sini
    // ...
    }
}
```

#### 3. Memudahkan Testing

```go
// Dalam testing, kita bisa pakai mock
type MockVehicle struct{}
func (m MockVehicle) Move() string { return "Mock bergerak" }

func TestDelivery(t *testing.T) {
    // Ganti factory dengan mock
    originalFactory := NewVehicle
    NewVehicle = func(tipe string) (Vehicle, error) {
        return MockVehicle{}, nil
    }
    
    // Jalankan test...
    
    // Kembalikan factory asli
    NewVehicle = originalFactory
}
```

### Perbandingan dengan Terminologi OOP Tradisional

| Istilah OOP tradisional | Ekuivalen di Go                        |
| ----------------------- | -------------------------------------- |
| Superclass              | Interface                              |
| Subclass                | Struct yang mengimplementasi interface |
| Method overriding       | Implementasi method pada struct        |
| Constructor             | Factory function                       |

### Kesimpulan

Factory Pattern di Go bukan tentang "subclass yang mengubah tipe objek", melainkan tentang:

1. **Menyediakan fungsi khusus** (factory function) untuk membuat objek
2. **Mengembalikan interface** bukan struct konkret
3. **Menyembunyikan detail implementasi** dari kode yang menggunakan objek
4. **Memungkinkan perubahan implementasi** tanpa mengubah kode client

Ini membuat kode lebih:

* **Modular**: Logika pembuatan terpisah dari penggunaan
* **Fleksibel**: Mudah mengganti implementasi
* **Testable**: Mudah membuat mock untuk testing
* **Mudah dipahami**: Kode client lebih sederhana

Dengan Factory Pattern, kita bisa fokus pada "apa" yang kita butuhkan (mobil, motor, dll) tanpa perlu pusing dengan "bagaimana" cara membuatnya.
