Pembaca seperti Anda membantu mendukung MUO. Saat Anda melakukan pembelian menggunakan tautan di situs kami, kami dapat memperoleh komisi afiliasi. Baca selengkapnya.

Salah satu prinsip terpenting dalam pengembangan perangkat lunak adalah prinsip desain terbuka-tertutup. Prinsip desain ini menekankan bahwa kelas harus terbuka untuk perluasan, tetapi tertutup untuk modifikasi. Pola desain dekorator mewujudkan prinsip desain buka-tutup.

Dengan pola desain dekorator, Anda dapat dengan mudah memperluas kelas dengan memberinya perilaku baru tanpa mengubah kode yang sudah ada. Pola dekorator melakukan ini secara dinamis saat runtime, menggunakan komposisi. Pola desain ini dikenal sebagai alternatif yang fleksibel untuk menggunakan warisan untuk memperluas perilaku.

Bagaimana Pola Desain Dekorator Bekerja?

Padahal pola dekorator merupakan alternatif dari pewarisan kelas, itu menggabungkan beberapa aspek warisan dalam desainnya. Aspek kunci dari pola dekorator adalah bahwa semua kelasnya terkait, baik secara langsung maupun tidak langsung.

instagram viewer

Pola desain dekorator tipikal memiliki struktur berikut:

Dari class diagram di atas dapat dilihat bahwa pola dekorator memiliki empat kelas utama.

Komponen: ini adalah kelas abstrak (atau antarmuka), yang berfungsi sebagai supertipe untuk pola dekorator.

Komponen Beton: ini adalah objek yang dapat Anda hiasi dengan perilaku berbeda saat runtime. Mereka mewarisi dari antarmuka komponen dan mengimplementasikan fungsi abstraknya.

Penghias: kelas ini abstrak dan memiliki supertipe yang sama dengan objek yang akan didekorasi. Dalam diagram kelas, Anda akan melihat dua hubungan antara kelas komponen dan dekorator. Hubungan pertama adalah hubungan pewarisan; setiap dekorator adalah komponen. Hubungan kedua adalah komposisi; masing-masing dekorator mempunyai sebuah (atau membungkus a) komponen.

Dekorator Beton: ini adalah dekorator individu yang memberikan komponen perilaku tertentu. Anda harus mencatat bahwa setiap dekorator beton memiliki variabel instan yang menyimpan referensi ke suatu komponen.

Menerapkan Pola Desain Dekorator di Jawa

Contoh aplikasi pemesanan pizza dapat mendemonstrasikan secara memadai bagaimana menggunakan pola dekorator untuk mengembangkan aplikasi. Aplikasi sampel pizza ini memungkinkan pelanggan untuk memesan pizza dengan banyak topping. Kelas pertama dari pola dekorator adalah antarmuka pizza:

publikantarmukaPizza{
publikabstrak Rangkaian keterangan();
publikabstrakdobelbiaya();
}

Antarmuka Pizza adalah kelas komponen. Jadi, Anda dapat membuat satu atau lebih kelas konkret darinya. Perusahaan pizza membuat dua jenis pizza utama, berdasarkan adonannya. Satu jenis pizza memiliki adonan ragi:

publikkelasYeastCrustPizzaalatPizza{
@Mengesampingkan
publik Rangkaian keterangan(){
kembali"Adonan pizza dibuat dengan ragi";
}

@Mengesampingkan
publikdobelbiaya(){
kembali18.00;
}
}

YeastCrustPizza adalah beton pertama kelas Jawa antarmuka Pizza. Jenis pizza lain yang tersedia adalah roti pipih:

publikkelasRoti pipihCrustPizzaalatPizza{
@Mengesampingkan
publik Rangkaian keterangan(){
kembali"Adonan pizza dibuat dengan roti pipih";
}

@Mengesampingkan
publikdobelbiaya(){
kembali15.00;
}
}

Kelas FlatbreadCrustPizza adalah komponen konkret kedua dan, seperti kelas YeastCrustPizza, mengimplementasikan semua fungsi abstrak dari antarmuka Pizza.

Para Dekorator

Kelas dekorator selalu abstrak, jadi Anda tidak dapat membuat instance baru langsung darinya. Tetapi penting untuk membangun hubungan antara dekorator yang berbeda dan komponen yang akan mereka hias.

publikabstrakkelasToppingDecoratoralatPizza{
publik Rangkaian keterangan(){
kembali"Topping Tidak Diketahui";
}
}

Kelas ToppingDecorator mewakili kelas dekorator dalam contoh aplikasi ini. Sekarang perusahaan pizza dapat membuat banyak topping (atau dekorator) yang berbeda, menggunakan kelas ToppingDecorator. Katakanlah sebuah pizza bisa memiliki tiga jenis topping yang berbeda, yaitu keju, pepperoni, dan jamur.

Taburan keju

publikkelasKejumemanjangToppingDecorator{
pribadi pizza pizza;

publikKeju(Pizza piza){
ini.pizza = pizza;
}

@Mengesampingkan
publik Rangkaian keterangan(){
kembali pizza.deskripsi() + ", toping keju";
}

@Mengesampingkan
publikdobelbiaya(){
kembaliPizza.biaya() + 2.50;
}
}

Topping peperoni

publikkelasPeperonimemanjangToppingDecorator{
pribadi pizza pizza;

publikPeperoni(Pizza piza){
ini.pizza = pizza;
}

@Mengesampingkan
publik Rangkaian keterangan(){
kembali pizza.deskripsi() + ", Topping Pepperoni";
}

@Mengesampingkan
publikdobelbiaya(){
kembaliPizza.biaya() + 3.50;
}
}

Toping jamur

publikkelasJamurmemanjangToppingDecorator{
pribadi pizza pizza;

publikJamur(Pizza piza){
ini.pizza = pizza;
}

@Mengesampingkan
publik Rangkaian keterangan(){
kembali pizza.deskripsi() + ", topping jamur";
}

@Mengesampingkan
publikdobelbiaya(){
kembaliPizza.biaya() + 4.50;
}
}

Sekarang Anda memiliki aplikasi sederhana yang diimplementasikan menggunakan pola desain dekorator. Jika pelanggan memesan pizza kerak ragi dengan keju dan pepperoni, kode uji untuk skenario tersebut akan terlihat sebagai berikut:

publikkelasUtama{
publikstatisruang kosongutama(String[] argumen){
Pizza pizza1 = baru YeastCrustPizza();
pizza1 = baru Pepperoni (pizza1);
pizza1 = baru Keju (pizza1);
System.out.println (pizza1.description() + " $" + pizza1.biaya());
}
}

Menjalankan kode ini akan menghasilkan keluaran berikut di konsol:

Seperti yang Anda lihat, output menyatakan jenis pizza beserta total biayanya. Pizza dimulai sebagai pizza kerak ragi seharga $ 18,00, tetapi dengan pola dekorator, aplikasi dapat menambahkan fitur baru dan biaya yang sesuai untuk pizza. Dengan demikian, memberikan pizza perilaku baru tanpa mengubah kode yang sudah ada (pizza kerak ragi).

Dengan pola dekorator, Anda juga dapat menerapkan perilaku yang sama ke objek sebanyak yang Anda inginkan. Jika pelanggan memesan pizza dengan semua yang ada di dalamnya, dan beberapa keju tambahan, Anda dapat memperbarui kelas utama dengan kode berikut untuk mencerminkan hal ini:

Pizza pizza2 = baru YeastCrustPizza();
pizza2 = baru Pepperoni (pizza2);
pizza2 = baru Keju (pizza2);
pizza2 = baru Keju (pizza2);
pizza2 = baru Jamur (pizza2);

System.out.println (pizza2.description() + " $" + pizza2.biaya());

Aplikasi yang diperbarui akan menghasilkan keluaran berikut di konsol:

Keuntungan Menggunakan Pola Desain Dekorator

Dua keuntungan utama menggunakan pola desain dekorator adalah keamanan dan fleksibilitas. Pola dekorator memungkinkan Anda mengembangkan kode yang lebih aman dengan tidak mengganggu kode aman yang sudah ada sebelumnya. Itu malah memperluas kode yang ada melalui komposisi. Secara efektif mencegah pengenalan bug baru atau efek samping yang tidak diinginkan.

Karena komposisi, pengembang juga memiliki banyak fleksibilitas saat menggunakan pola dekorator. Anda dapat mengimplementasikan dekorator baru kapan saja untuk menambahkan perilaku baru, tanpa mengubah kode yang ada dan mengganggu aplikasi.