Pola Dekorator di Jawa

1. Ikhtisar

Pola Dekorator dapat digunakan untuk melampirkan tanggung jawab tambahan ke suatu objek baik secara statis atau dinamis. Dekorator menyediakan antarmuka yang disempurnakan ke objek aslinya.

Dalam penerapan pola ini, kami lebih memilih komposisi daripada pewarisan - sehingga kami dapat mengurangi overhead subclass berulang kali untuk setiap elemen dekorasi. Rekursi yang terlibat dengan desain ini dapat digunakan untuk mendekorasi objek kami sebanyak yang kami butuhkan.

2. Contoh Pola Dekorator

Misalkan kita memiliki sebuah objek pohon natal dan ingin menghiasnya. Dekorasi tidak mengubah objek itu sendiri; hanya saja selain pohon natal, kami menambahkan beberapa item dekorasi seperti karangan bunga, perada, puncak pohon, lampu gelembung, dll .:

Untuk skenario ini, kita akan mengikuti desain asli Gang of Four dan konvensi penamaan. Pertama, kita akan membuat antarmuka ChristmasTree dan implementasinya:

public interface ChristmasTree { String decorate(); }

Implementasi antarmuka ini akan terlihat seperti:

public class ChristmasTreeImpl implements ChristmasTree { @Override public String decorate() { return "Christmas tree"; } }

Sekarang kita akan membuat kelas TreeDecorator abstrak untuk pohon ini. Dekorator ini akan mengimplementasikan antarmuka ChristmasTree serta menyimpan objek yang sama. Metode yang diimplementasikan dari antarmuka yang sama hanya akan memanggil metode decorate () dari antarmuka kami:

public abstract class TreeDecorator implements ChristmasTree { private ChristmasTree tree; // standard constructors @Override public String decorate() { return tree.decorate(); } }

Sekarang kita akan membuat beberapa elemen dekorasi. Dekorator ini akan memperluas kelas TreeDecorator abstrak kami dan akan memodifikasi metode decorate () sesuai dengan kebutuhan kami:

public class BubbleLights extends TreeDecorator { public BubbleLights(ChristmasTree tree) { super(tree); } public String decorate() { return super.decorate() + decorateWithBubbleLights(); } private String decorateWithBubbleLights() { return " with Bubble Lights"; } }

Untuk kasus ini, berikut ini benar:

@Test public void whenDecoratorsInjectedAtRuntime_thenConfigSuccess() { ChristmasTree tree1 = new Garland(new ChristmasTreeImpl()); assertEquals(tree1.decorate(), "Christmas tree with Garland"); ChristmasTree tree2 = new BubbleLights( new Garland(new Garland(new ChristmasTreeImpl()))); assertEquals(tree2.decorate(), "Christmas tree with Garland with Garland with Bubble Lights"); }

Perhatikan bahwa di objek tree1 pertama , kami hanya menghiasnya dengan satu Garland saja , sedangkan objek tree2 lainnya kami dekorasi dengan satu BubbleLights dan dua Garland . Pola ini memberi kita fleksibilitas untuk menambahkan dekorator sebanyak yang kita inginkan saat runtime.

4. Kesimpulan

Pada artikel ini, kita telah melihat pola desain dekorator. Ini adalah pilihan yang baik dalam kasus berikut:

  • Ketika kita ingin menambah, meningkatkan atau bahkan menghilangkan perilaku atau keadaan objek
  • Ketika kita hanya ingin mengubah fungsionalitas dari satu objek kelas dan membiarkan yang lain tidak berubah

Kode sumber lengkap untuk contoh ini tersedia di GitHub.