1. Apa itu Pola Dekorator
Pola dekorator adalah pola desain struktural yang memungkinkan penambahan fitur tambahan ke dalam objek secara dinamis tanpa memodifikasi kode objek tersebut. Hal ini dicapai dengan melingkupi objek dalam sebuah kelas dekorator, memberikan kemampuan untuk menambah, memodifikasi, atau meningkatkan perilaku objek saat runtime.
2. Karakteristik dan Kelebihan Pola Dekorator
Karakteristik dan kelebihan dari pola dekorator meliputi:
- Memperluas fungsionalitas suatu objek secara dinamis tanpa memodifikasi kode tersebut.
- Patuh terhadap Prinsip Terbuka-Tertutup, memungkinkan penambahan dan penghapusan dekorator secara dinamis.
- Kemampuan untuk menggabungkan beberapa dekorator untuk mencapai perluasan fungsionalitas bertingkat.
- Dekorator independen dari cara objek dihias, memungkinkan perubahan dilakukan secara independen.
3. Contoh Aplikasi Praktis dari Pola Dekorator
Pola dekorator memiliki banyak aplikasi praktis dalam pengembangan perangkat lunak, seperti:
- Menambahkan fungsionalitas logging secara dinamis
- Menambahkan fungsionalitas caching secara dinamis
- Validasi data dinamis
4. Implementasi Pola Dekorator di Golang
4.1. Diagram Kelas UML
4.2. Pengantar Contoh
Dalam contoh ini, kita memiliki sebuah antarmuka Komponen dan sebuah kelas ConcreteComponent yang mengimplementasikan metode Operasi dari antarmuka Komponen.
Kemudian kita memiliki sebuah kelas Dekorator yang juga mengimplementasikan antarmuka Komponen. Kelas Dekorator memiliki variabel anggota bertipe Komponen.
Kedua kelas ConcreteDecoratorA dan ConcreteDecoratorB mewarisi dari kelas Dekorator dan mengimplementasikan fungsionalitas tambahan dengan mengganti metode Operasi.
4.3. Langkah Implementasi 1: Mendefinisikan antarmuka dan kelas implementasi
type Component interface {
Operation() string
}
type ConcreteComponent struct {}
func (c *ConcreteComponent) Operation() string {
return "operasi komponen spesifik"
}
4.4. Langkah Implementasi 2: Mendefinisikan dekorator
type Decorator struct {
component Component
}
func (d *Decorator) Operation() string {
return d.component.Operation()
}
4.5. Langkah Implementasi 3: Implementasi dekorator
type ConcreteDecoratorA struct {
Decorator
addedState string
}
func (c *ConcreteDecoratorA) Operation() string {
c.addedState = "State Baru"
return c.addedState + " " + c.component.Operation()
}
type ConcreteDecoratorB struct {
Decorator
}
func (c *ConcreteDecoratorB) Operation() string {
return "operasi dekorator B spesifik " + c.component.Operation()
}
4.6. Langkah Implementasi 4: Menggunakan dekorator
func main() {
komponen := &ConcreteComponent{}
dekoratorA := &ConcreteDecoratorA{}
dekoratorA.component = komponen
dekoratorB := &ConcreteDecoratorB{}
dekoratorB.component = dekoratorA
hasil := dekoratorB.Operation()
fmt.Println(hasil)
}
5. Perbandingan Pola Dekorator dengan Pola Desain Lain
5.1. Perbandingan dengan Pewarisan
Dibandingkan dengan pewarisan, pola dekorator dapat dinamis menambahkan fungsionalitas tanpa memodifikasi kode yang ada, sedangkan pewarisan adalah statis dan perlu ditentukan saat waktu kompilasi.
5.2. Perbandingan dengan Pola Proxy Statis
Pola dekorator dan pola proxy statis dapat sama-sama mencapai perluasan fungsi, namun pola dekorator lebih fleksibel dan memungkinkan penambahan dan penghapusan fungsionalitas secara dinamis.
5.3. Perbandingan dengan Pola Proxy Dinamis
Baik pola dekorator maupun pola proxy dinamis dapat memperluas fungsionalitas objek saat runtime. Namun, pola dekorator menghias sebuah objek tunggal, sementara pola proxy dinamis melibatkan akses tidak langsung antara objek proxy dan objek target.