← 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"