Kamis, 05 Juli 2012

Decorator Patern

Konteks:
- Diinginkan untuk memperkaya behaviour dari suatu class. Kita sebut class ini class komponen.
- Objek komponen terdekorasi bisa digunakan sama seperti objek komponen biasa.
- Tanggung jawab dari proses dekorasi tidak diinginkan ada pada class komponen.
- Kemungkinan ada proses dekorasi yang ditambahkan di masa depan yang tak bisa diperkirakan dan harus diantisipasi.

Solusi:
- Definisikan suatu tipe interface yang merupakan abstraksi dari class komponen.
- Class kongkrit komponen mengimplementasikan tipe interface ini.
- Class decorator juga mengimplementasikan tipe interface ini.
- Sebuah objek decorator mengatur objek komponen yang didekorasinya.
- Ketika mendefisikan method dari tipe interface (pada poin 1), class decorator memanggil method yang sama milik objek komponen yang didekorasinya dan mengkombinasikan hasilnya dengan efek dari proses dekorasi.

Image

Contoh:
Java Swing Component.
Komponen Swing seperti JTextArea dan JPanel dapat didekorasi dengan menambahkan scrollbar. Komponen lain seperti tree juga mungkin bisa memanfaatkan scrollbar. Untuk menambahkan scrollbar, dibuat objek JScrollPane dengan menambahkan objek yang didekorasinya sebagai parameter.
Code: Select all
JPanel panel = new JPanel();
.....
JScrollPane scroller = new JScrollPane(panel);

Dengan pendekatan seperti ini, class JPanel tidak perlu bertanggung jawab tentang bagaimana efek dekorasi mempengaruhi tampilan dari isinya. Juga, kita mungkin mendefinisikan sendiri class yang men-zoom tampilan suatu panel dengan menggeser scrollbar pada panel tersebut, dengan menurunkan dari class JScrollPane.
Code: Select all
public class JScrollZoomPane extends JScrollPane
{
.....
}

Code: Select all
JPanel panel = new JPanel(); ..... JScrollZoomPane zoomer = new JScrollZoomPane(panel);

Perhatikan dari class diagram di atas pattern Decorator mirip dengan Composite, tetapi hubungan antara class decorator dan class komponennya adalah hubungan 1:1, yaitu satu objek decorator mendekorasi satu objek komponen (pada pattern Composite, hubungannya 1:n, satu objek komposit mengandung satu atau lebih objek primitif).
Contoh lain pattern Decorator misalnya kita modifikasi contoh dari pattern Composite. Suatu Item yang di-discount diperlakukan sama seperti Item yang tidak di-discount, tetapi proses pemotongan harga dilakukan oleh suatu class dekorator, bukan oleh class Item itu sendiri.
Code: Select all
public class DiscountedItem implements Item {   public DiscountedItem(Item item, double discount){     this.item = item;     this.discount = discount;   }   .....   public double getPrice(){     return item.getPrice * (1 - discount/100);   }   .....   private Item item;   private double discount; } public class HomeTheater {   .....   private ArrayList items = new ArrayList();   .....   public void addItem(Item item){     items.add(item);   }   public double getPrice(){     // calculate total sum price from individual item in collection and discount it.     // See that this method calls individual item's method with the same name     // and augments the result with its own calculation.     double overallPrice;     for(Item item : items)       overallPrice += item.getPrice();     return overallPrice;   }   ..... }

Proses pemotongan harga di atas tidak lagi dari class HomeTheater itu sendiri, melainkan dari class dekorator DiscountedItem. Method HomeTheater.getPrice() hanya melakukan penjumlahan dari method getPrice() masing-masing elemennya. Karena DiscountedItem sendiri mengimplementasikan (CAN_BE_USED_AS) Item, maka objek dari Item, HomeTheater (merupakan class komposit), dan DiscountedItem (class dekorator) semuanya diperlakukan sebagai Item.
Code: Select all
// Client code ..... HomeTheater deluxeHomeTheater = new HomeTheater(); deluxeHomeTheater.addItem(new PlasmaTV(...)); deluxeHomeTheater.addItem(new DVDPlayer(...)); deluxeHomeTheater.addItem(new AudioSystem(...)); deluxeHomeTheater.addItem(new LCDProjector(...)); deluxeHomeTheater.addItem(new ProjectorScreen(...)); deluxeHomeTheater.addItem(new TVRack(...)); ..... ArrayList onSaleItems = new ArrayList(); onSaleItems.add(new PlasmaTV); onSaleItems.add(new TVRack);

0 komentar:

Posting Komentar