← Kembali ke Design Pattern
🚦
Behavioral

State

Memungkinkan sebuah objek mengubah perilakunya saat state internalnya berubah, seolah-olah class-nya ikut berubah.

Masalahnya

Perilaku sebuah objek bergantung pada state-nya saat ini, sehingga muncul if/else atau switch besar yang tersebar di banyak method, semuanya memeriksa state saat ini.

Cara Kerja

  • ›Setiap state adalah class terpisah yang membungkus perilaku untuk state tersebut
  • ›Transisi state dilakukan dengan mengganti objek state saat ini
  • ›Menghilangkan logika kondisional rumit yang tersebar di banyak method
  • ›State baru bisa ditambahkan tanpa mengubah class state yang sudah ada (Open/Closed)
  • ›Context mendelegasikan semua perilaku yang bergantung pada state ke objek state saat ini

Kapan Digunakan

✓Perilaku objek harus berubah berdasarkan state-nya saat runtime
✓Finite state machine: siklus hidup pesanan, status koneksi, status player
✓Saat kode khusus state terduplikasi di banyak cabang kondisional
✓Saat transisi antar state perlu eksplisit dan terdefinisi dengan jelas

Contoh di Dunia Nyata

🍎
iOS

UIViewController lifecycle (viewDidLoad → viewWillAppear → viewDidAppear), AVPlayer state

🤖
Android

Fragment backstack, MediaPlayer states (Idle→Initialized→Prepared→Started), ViewModel state flows

🌐
Web

Promise states (pending/fulfilled/rejected), XState FSM, React component lifecycle

Contoh Kode

Swift
protocol OrderState {
    var label: String { get }
    func next(order: Order)
}

class Order {
    var state: OrderState = PendingState()
    func advance() { state.next(order: self) }
    func status()  { print("Order: \(state.label)") }
}

class PendingState: OrderState {
    var label = "Pending"
    func next(order: Order) { order.state = ProcessingState() }
}
class ProcessingState: OrderState {
    var label = "Processing"
    func next(order: Order) { order.state = ShippedState() }
}
class ShippedState: OrderState {
    var label = "Shipped"
    func next(order: Order) { order.state = DeliveredState() }
}
class DeliveredState: OrderState {
    var label = "Delivered"
    func next(order: Order) { print("Already delivered") }
}

let order = Order()
order.status()   // "Order: Pending"
order.advance(); order.status()   // "Order: Processing"
order.advance(); order.status()   // "Order: Shipped"
order.advance(); order.status()   // "Order: Delivered"