6.2 KiB
title, category, language, tag
| title | category | language | tag | ||
|---|---|---|---|---|---|
| Decorator | Structural | id |
|
Juga dikenal sebagai
Pembungkus
Tujuan
Menyematkan tanggung jawab tambahan ke suatu objek secara dinamis. Dekorator memberikan alternatif yang fleksibel terhadap subkelas untuk memperluas fungsionalitas.
Penjelasan
Contoh dunia nyata
Ada troll pemarah yang tinggal di perbukitan terdekat. Biasanya ia pergi dengan tangan kosong, tetapi terkadang ia punya senjata. Untuk mempersenjatai troll, Anda tidak perlu membuat troll baru, melainkan mendekorasinya secara dinamis dengan senjata yang sesuai.
Dengan kata sederhana
Pola dekorator memungkinkan Anda mengubah perilaku objek secara dinamis saat run time dengan membungkus mereka dalam objek kelas dekorator.
Wikipedia(en) mengatakan
Dalam pemrograman berorientasi objek, pola dekorator adalah pola desain yang memungkinkan perilaku ditambahkan ke objek individual, baik secara statis maupun dinamis, tanpa memengaruhi perilaku objek lain dari kelas yang sama. Pola dekorator sering kali berguna untuk mematuhi Prinsip Tanggung Jawab Tunggal, karena memungkinkan fungsionalitas dibagi antara kelas-kelas dengan area perhatian yang unik serta Prinsip Terbuka-Tertutup, dengan memungkinkan fungsionalitas suatu kelas diperluas tanpa diubah.
Contoh Program
Mari kita ambil contoh troll. Pertama-tama kita memiliki SimpleTroll yang mengimplementasikan antarmuka
Troll:
public interface Troll {
void attack();
int getAttackPower();
void fleeBattle();
}
@Slf4j
public class SimpleTroll implements Troll {
@Override
public void attack() {
LOGGER.info("Troll itu mencoba menangkapmu!");
}
@Override
public int getAttackPower() {
return 10;
}
@Override
public void fleeBattle() {
LOGGER.info("Troll itu menjerit ketakutan dan melarikan diri!");
}
}
Kemudian kita ingin menambahkan gada untuk troll tersebut. Kita dapat melakukannya secara dinamis dengan menggunakan dekorator:
@Slf4j
public class ClubbedTroll implements Troll {
private final Troll decorated;
public ClubbedTroll(Troll decorated) {
this.decorated = decorated;
}
@Override
public void attack() {
decorated.attack();
LOGGER.info("Troll itu mengayunkan gada ke arahmu!");
}
@Override
public int getAttackPower() {
return decorated.getAttackPower() + 10;
}
@Override
public void fleeBattle() {
decorated.fleeBattle();
}
}
Berikut aksi troll tersebut:
// simple troll
LOGGER.info("Troll biasa mendekat.");
var troll = new SimpleTroll();
troll.attack();
troll.fleeBattle();
LOGGER.info("Kekuatan troll sederhana: {}.\n", troll.getAttackPower());
// change the behavior of the simple troll by adding a decorator
LOGGER.info("Troll dengan gada besar mengejutkanmu.");
var clubbedTroll = new ClubbedTroll(troll);
clubbedTroll.attack();
clubbedTroll.fleeBattle();
LOGGER.info("Kekuatan troll dengan gada: {}.\n", clubbedTroll.getAttackPower());
Output program:
Troll biasa mendekat.
Troll itu mencoba menangkapmu!
Troll itu menjerit ketakutan dan melarikan diri!
Kekuatan troll sederhana: 10.
Troll dengan gada besar mengejutkanmu.
Troll itu mencoba menangkapmu!
Troll itu mengayunkan gada ke arahmu!
Troll itu menjerit ketakutan dan melarikan diri!
Kekuatan troll dengan gada: 20.
Diagram kelas
Penerapan
Dekorator digunakan untuk:
- Tambahkan tanggung jawab ke objek individual secara dinamis dan transparan, tanpa memengaruhi objek lain.
- Untuk tanggung jawab yang dapat ditarik/dihapus.
- Dimana ekstensi dengan subkelas tidak praktis; Ketika sejumlah besar ekstensi independen mungkin dilakukan dan akan menghasilkan ledakan subkelas untuk mendukung setiap kombinasi, atau definisi kelas mungkin tersembunyi dan/atau tidak tersedia untuk subkelas.
Tutorial
Kegunaan yang diketahui
- java.io.InputStream, java.io.OutputStream, java.io.Reader dan java.io.Writer
- java.util.Collections#synchronizedXXX()
- java.util.Collections#unmodifiableXXX()
- java.util.Collections#checkedXXX()
