This is default featured slide 1 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions.

This is default featured slide 2 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions.

This is default featured slide 3 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions.

This is default featured slide 4 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions.

This is default featured slide 5 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions.

Kamis, 05 Juli 2012

Strategi Method Patern

Penerapan design pattern Strategy di Java

07 May
Strategy pattern (juga dikenal sebagai kebijakan pola) adalah pola desain perangkat lunak tertentu, dimana algoritma dapat dipilih saat runtime. Secara resmi berbicara, strategi pola mendefinisikan sebuah keluarga algoritma, merangkum masing-masing, dan membuat mereka saling dipertukarkan. Strategi ini memungkinkan algoritma yang bervariasi secara independen dari klien yang menggunakannya.[1]
Sebagai contoh, sebuah kelas yang melakukan validasi pada data yang masuk dapat menggunakan pola strategi untuk memilih algoritma validasi yang didasarkan pada jenis data, sumber data, pilihan pengguna, dan faktor-faktor lain yang membedakan, atau. Faktor-faktor ini tidak diketahui untuk setiap kasus sampai run-time, dan mungkin memerlukan validasi yang berbeda untuk dilakukan. Strategi validasi, dikemas secara terpisah dari objek memvalidasi, dapat digunakan oleh benda-benda lain memvalidasi dalam berbagai bidang sistem (atau bahkan berbagai sistem) tanpa duplikasi kode.
Persyaratan penting dalam bahasa pemrograman adalah kemampuan untuk menyimpan referensi untuk beberapa kode dalam struktur data dan mengambilnya. Ini dapat dicapai dengan mekanisme seperti pointer asli fungsi, fungsi kelas, kelas atau kelas contoh dalam berorientasi objek bahasa pemrograman, atau mengakses penyimpanan internal implementasi bahasa kode melalui refleksi.
Structure :
Contoh di Java
// The classes that implement a concrete strategy should implement this.
// The context class uses this to call the concrete strategy.
interface Strategy {
    int execute(int a, int b); 
}

// Implements the algorithm using the strategy interface
class ConcreteStrategyAdd implements Strategy {

    public int execute(int a, int b) {
        System.out.println("Called ConcreteStrategyAdd's execute()");
        return a + b;  // Do an addition with a and b
    }
}

class ConcreteStrategySubtract implements Strategy {

    public int execute(int a, int b) {
        System.out.println("Called ConcreteStrategySubtract's execute()");
        return a - b;  // Do a subtraction with a and b
    }
}

class ConcreteStrategyMultiply implements Strategy {

    public int execute(int a, int b) {
        System.out.println("Called ConcreteStrategyMultiply's execute()");
        return a * b;   // Do a multiplication with a and b
    }    
}

// Configured with a ConcreteStrategy object and maintains a reference to a Strategy object
class Context {

    private Strategy strategy;

    // Constructor
    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public int executeStrategy(int a, int b) {
        return strategy.execute(a, b);
    }
}

// Test application
class StrategyExample {

    public static void main(String[] args) {

        Context context;

        // Three contexts following different strategies
        context = new Context(new ConcreteStrategyAdd());
        int resultA = context.executeStrategy(3,4);

        context = new Context(new ConcreteStrategySubtract());
        int resultB = context.executeStrategy(3,4);

        context = new Context(new ConcreteStrategyMultiply());
        int resultC = context.executeStrategy(3,4);
    }
}

Share this:

Template Patern

Sungguh mengasyikkan belajar java, betapa tidak ia terkadang membuatku gk bisa tidur karena asyik ngoprek. apalagi klu udah sampai belajar design pattern, wuuuh…bener-bener mantap (this is the real OOP menurutku..hehehe..). salah satu metoda didalamnya adalah template pattern butuh waktu khusus (bertapa di gua sampai brewokan) diriku untuk bener-bener memahami konsepsi dan filosofinya yang lumayan mak-nyooosss…sebetulnya design pattern untuk memahami konsepsi dan filosofi keseluruhannya juga Top Markotop Mak-nyooos (pak bondan,red)..tapi insya Allah klu sudah mengerti konsepnya kesananya jadi sedikit mudah kok (sedikit mudah, banyak sulitnya..wekekeke).
singkat kata berikut adalah contoh Source Code sederhana metoda Template Pattern yang saya tulis menggunakan java  :
/*
contoh template pattern
author m42h31
param none
*/

public abstract class Motor{
protected String noPol;
protected static String merek,model;
protected final static int A1=100,A2=10;
protected final static int B1=1000,B2=100;
protected String warna=”Black”;
protected String jenisPembayaran=”Tunai”;
private static float bbm=0.06f;
private static int jml=0;
private static int tahun=2004;
private static int cc=A1;
private static int hargaPokok;
private static int bunga;
protected static int hargaBayar;
public Motor(){}
public Motor(String np,String mrk,String mdl){
noPol=np;
merek=mrk;
model=mdl;
jml++;
}
public void tahunPertama(){
System.out.println(“Tahun Produksi :”+tahun+”,Jumlah Motor : “+jml);
System.out.println(“=============================”);
}
public void nextTahun(){
hargaPokok+=100;
tahun++;
tahunPertama();
}
public void head(){
System.out.println(“Nomer Polisi : “+getNoPol());
System.out.println(“Merek : “+getMerek());
System.out.println(“Model : “+getModel());
System.out.println(“Warna : “+getWarna());
System.out.println(“JenisPembayaran : “+jenisPembayaran);
}
public abstract void harga();
public void tail(){
System.out.println(“BBM : “+bbm+” liter/km”);
System.out.println(“Besaran CC : “+cc+” cc”);
System.out.println(“============================”);
}
public void cetak(){
head();
harga();
tail();
}
public static void tambahCc(){
cc+=A2;
bbm-=0.01f;
hargaPokok+=500;
}
public void setWarna(String wr){
warna=wr;
}
public void setJenisPembayaran(String jp){
jenisPembayaran=jp;
}
public void setHargaPokok(int hp){
hargaPokok=hp;
}
public void setBunga(int bg){
bunga=bg;
}
public int getHargaPokok(){
return hargaPokok;
}
public int getBunga(){
return bunga;
}
public int getHargaBayar(){
return hargaBayar=hargaPokok+bunga;
}
public String getNoPol(){
return noPol;
}
public String getMerek(){
return merek;
}
public String getModel(){
return model;
}
public String getWarna(){
return warna;
}
}
public class Tunai extends Motor{
public Tunai(String np,String mrk,String mdl){
super(np,mrk,mdl);
}
public String getNopol(){
return noPol;
}
public String getMerek(){
return merek;
}
public String getModel(){
return model;
}
public void harga(){
System.out.println(“Harga Pokok : “+getHargaPokok());
System.out.println(“Harga Bayar : “+getHargaBayar());
}
}
public class Kredit extends Motor{
public Kredit(Tunai tun){
noPol=tun.getNoPol();
merek=tun.getMerek();
model=tun.getModel();
warna=tun.getWarna();
setBunga(B2);
tun.hargaBayar=getHargaPokok()+getBunga();
setJenisPembayaran(“Kredit”);
}
public void harga(){
System.out.println(“Harga Pokok : “+getHargaPokok());
System.out.println(“Bunga :”+getBunga());
System.out.println(“Harga Bayar : “+getHargaBayar());
}
}
class testMotor{
public static void main(String []args){
Tunai vg=new Tunai(“D3154FA”,”Yamaha”,”Vega”);
vg.setHargaPokok(10000);
vg.setWarna(“biru”);
vg.tahunPertama();
vg.cetak();
vg.nextTahun();
vg.tambahCc();
vg.cetak();
Tunai sp=new Tunai(“D4353GD”,”Honda”,”Supra”);
sp.setHargaPokok(14000);
sp.setWarna(“merah”);
sp.tahunPertama();
sp.cetak();
Kredit spk=new Kredit(sp);
spk.cetak();
spk.tambahCc();
spk.cetak();
spk.nextTahun();
spk.tambahCc();
spk.cetak();
}
}

Facade Patern

Façade adalah interface dimana aplikasi dapat menggunakannya untuk melakukan sesuatu tanpa mengkhawatirkan mengenai detail-detail yang terlibat. Façade memisahkan layer-layer yang terlibat sehingga layer-layer tersebut tidak bergantung satu sama lainnya dimana membuat masing-masing layer dapat dengan mudah untuk dikembangkan, mudah untuk digunakan, dan mempertimbangkan untuk menggunakan code re-use.                         .
Bagaimanapun juga, façade dapat menjadi sangat kompleks untuk subsistem yang sangat besar. Untuk itu, perlu ditambahkan abstract façade diatas façade yang telah ada. Salah satu contoh yang umum adalah dengan menggunakan pattern melalui webservice, dimana membuat webservice berperilaku sebagai façade atau interface terhadap banyak dll yang berbeda yang masing-masing merepresentasikan suatu subsistem tertentu.Kelas dan/atau objek yang berpartisipasi pada façade adalah:
  1. Façade (misal. MortgageApplication) Mengetahui kelas-kelas subsistem yang bertanggung jawab terhadap permintaan
  2. Mendelegasikan permintaan dari klien kepada objek subsistem yang bersesuaian
  3. Kelas subsistem (misal. Bank, Credit, Loan)
  4. Mengimplementasikan fungsionalitas dari subsiste
  5. Menangani pekerjaan yang diberikan oleh objek façade
  6. Tidak mempunyai pengetahuan mengenai façade dan tidak peduli dengan reference
mengenai hal ini
- TUJUAN FAÇADE PATTERN
Untuk menyediakan unifikasi interface pada sekumpulan interface yang terdapat pada sebuah subsystem, dimana façade akan mendefiniskan interface tingkatan yang lebih tinggi sehingga subsystem lebih mudadigunakan dengan menguraikan system kedalam subsystem untuk mengatasi kompleksitas sebuah system.
Transaksi ATM :
Dari pengertian di atas kami mengambil contoh Bank tetapi  hanya pada bagian transfer rekening. Di dalam proses rekening seorang client menginputkan  card ATM ke dalam mesin (Card reader) sehingga mesin tersebut akan membaca card ATM tersebut. Kemudian  client melakukan login dengan memasukkan PIN.  Setelah itu melakukan transaksi, termasuk ada pilihan antara transfer dan penarikan atau lainnya. karena  tujuannya hanya  melakukan  transfer rekening maka setelah mentransfer ke rekening tujuan,  setelah  itu lakukan proses bukti transfer  atau cetak resi dari sistem.
Alasan  menggunakan Façade pattern ?
Alasan  kenapa Aplikasi transfer ATM  menggunakan façade pattern, karena dapat menguraikan kompleksitas sistem transaksi ATM ke dalam sub system yang lebih mudah implementasikan.
Façade Pattern

Facade ATM  diatas  mempunyai 5 subsystem, yaitu client, printer, card reader, login, transaksi. di dalam subsystem transaksi memiliki subsystem lagi yatu menu transfer dan menu penarikan. masing – masing subsystem memiliki methode sesuai fungsingnya seperti yang sudah dijelaskan pada gambar di atas.
Class Diagram

-          Usecase

Activity Diagram

Sequence diagram



package login;
import java.util.*;
public class Login
{
private ArrayList loginHistory;
public Login(String newLogin) throws Exception
{
loginHistory = new ArrayList();
set(newLogin);
}
public void set(String login) throws Exception
{
boolean loginAdded = true;
login = login.trim();
loginAdded = loginHistory.add(login);
}
}//end of Login class
/**
* @(#)Message.java
*
*
* @author
* @version 1.00 2011/1/5
*/
package login;
import javax.swing.JOptionPane;
public abstract class Message {
public Message() {
}
public void pesanku(){
}
}
class Message2 extends Message{
public Message2(){
}
public void pesanku(){
JOptionPane.showMessageDialog(null,”SELAMAT DATANG DI PROGRAM KAMI \n\n PROGRAM INI DI BUAT OLEH”,”PROGRAM LOGIN”,JOptionPane.INFORMATION_MESSAGE);
}
}
public class Message2{
public Message2(){
}
public void pesanku(){
JOptionPane.showMessageDialog(null,”DAYAT”,”OLEH”,JOptionPane.INFORMATION_MESSAGE);
}
}
package login;
import login.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class LoginDemo
{
public static void main(String[] argv)
{
int width = 300;
int height = 200;
Message2 data=new Message2();
data.pesanku();
final demoFrame f = new demoFrame(“Program Login”);
f.pack();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(width, height);
f.centerOnScreen(width, height);
f.setVisible(true);
}
}//end class LoginDemo
class demoFrame extends JFrame implements ActionListener
{
Login login = null;
String userName;
String Password;
Integer counter = 0;
JTextField userNameField;
JTextField PasswordField;
JTextField userCountField;
JButton jbtLogOn, jbtLogOff, jbtExit;
public demoFrame(String title)
{
super(title);
JLabel label1 = new JLabel(“Username: “);
userNameField = new JTextField(10);
JLabel label2 = new JLabel (“Password : “);
PasswordField = new JTextField(10);
JLabel label3 = new JLabel(“Number of Users: “);
userCountField = new JTextField(5);
userCountField.setEditable(false);
jbtLogOn = new JButton(“Login”);
jbtLogOff = new JButton(“Logoff”);
jbtExit = new JButton(“Exit”);
jbtLogOn.addActionListener(this);
jbtLogOff.addActionListener(this);
jbtExit.addActionListener(this);
JPanel userPanel = new JPanel(new BorderLayout (10,10));
userPanel.add(label1, BorderLayout.WEST);
userPanel.add(userNameField, BorderLayout.EAST);
JPanel userPanel2 = new JPanel(new BorderLayout (10,10));
userPanel2.add(label2, BorderLayout.WEST);
userPanel2.add(PasswordField, BorderLayout.EAST);
JPanel buttonPanel = new JPanel(new FlowLayout());
buttonPanel.add(jbtLogOn);
buttonPanel.add(jbtLogOff);
buttonPanel.add(jbtExit);
JPanel userCountPanel = new JPanel(new BorderLayout(10,10));
userCountPanel.add(label3, BorderLayout.WEST);
userCountPanel.add(userCountField, BorderLayout.EAST);
JPanel contentPanel = new JPanel(new FlowLayout());
contentPanel.add(userPanel);
contentPanel.add(userPanel2);
contentPanel.add(userCountPanel);
contentPanel.add(buttonPanel);
setContentPane(contentPanel);
InputMap map;
map = jbtLogOn.getInputMap();
if (map != null)
{
map.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0,false), “pressed”);
map.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0,true), “release”);
}
map = jbtLogOff.getInputMap();
if (map != null)
{
map.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0,false), “pressed”);
map.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0,true), “release”);
}
}
public void centerOnScreen(int width, int height)
{
int top, left, x, y;
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
x = (screenSize.width – width)/2;
y = (screenSize.height – height)/2;
top = (x < 0) ? 0 : x;
left = (y < 0) ? 0 : y;
this.setLocation(top, left);
}
CobaSleep pesan = new CobaSleep();
public void actionPerformed(ActionEvent e)
{
try
{
if(e.getSource() == jbtLogOn)
{
userName = new String(userNameField.getText());
login = new Login(userName);
userNameField.requestFocus();
counter++;
userCountField.setText(counter.toString());
String user=”"; String pass=”";
user = userNameField.getText();
pass = PasswordField.getText();
if ((user.equals(“Hidayat”)) && (pass.equals(“dayat”))) {
pesan.tampil();
} else if ((user.equals(“OKI”)) && (pass.equals(“ok”))) {
pesan.tampil();
}else if ((user.equals(“Adel”)) && (pass.equals(“adel”))) {
pesan.tampil();
} else {
JOptionPane.showMessageDialog(null, “Username and password dosn’t match!”);
userNameField.setText(“hai”);
PasswordField.setText(“”);
System.out.println(“”+user+pass);
}
}
if(e.getSource() == jbtLogOff)
{
userNameField.setText(“”);
userNameField.requestFocus();
if(counter != 0)
{
counter–;
userCountField.setText(counter.toString());
}
else
{
JOptionPane.showMessageDialog(this, “No username yet logged in”, “Invalid userName. Try Again.”, JOptionPane.ERROR_MESSAGE);
}
}
if (e.getSource() == jbtExit)
{
JOptionPane.showMessageDialog(null,”Thanks to try my program. See you..”);
System.exit(0);
}
}
catch (NullPointerException ex)
{
JOptionPane.showMessageDialog(this, “No username yet logged in”, “Invalid userName. Try Again.”, JOptionPane.ERROR_MESSAGE);
}
catch (Exception ex)
{
JOptionPane.showMessageDialog(this, ex.getMessage(), “Invalid username. Try again.”, JOptionPane.ERROR_MESSAGE);
}
}
}//end class demoFrame

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);

Composite Pattern

Secara tidak sadar, berbagai program yang seringkali digunakan ternyata menggunakan composite pattern. Salah satu contoh aplikasi semisal, Microsoft Office Visio memungkinkan pengguna untuk dapat membuat berbagai bentuk semisal kotak, lingkaran, dan sebagainya. Kemudian pengguna dapat melakukan grouping terhadap bentuk-bentuk yang ada dan ketika group tersebut dipindahkan posisinya, otomatis semua shape yang ada dalam group tersebut ikut berpindah posisinya. Pengguna juga dapat melakukan grouping kembali terhadap group shape yang ada dengan shape-shape yang lain sehingga dapat terbentuk semacam hierarki pada shape yang ada. Bentuk-bentuk permasalahan semacam inilah yang dapat diselesaikan dengan Composite Pattern.
Sebagai kelanjutan dari postingan Strategy Pattern, kali ini program sederhana tersebut akan dikembangkan sehingga program tersebut dapat melakukan grouping terhadap shape kotak, lingkaran dan garis. Langkah-langkah yang harus dilakukan adalah sebagai berikut:
  1. Buat sebuah class Komposisi yang merupakan group dari shape yang ada
  2. 01///
    02/// Author: Jeffrey Hermanto Halimsetiawan
    03///
    04public class Komposisi : Shape
    05{
    06    private Point _origin;
    07 
    08    private List _gambar;
    09 
    10    public Point Origin
    11    {
    12        get
    13        {
    14            return _origin;
    15        }
    16        set
    17        {
    18            _origin = value;
    19        }
    20    }
    21 
    22    public Komposisi()
    23    {
    24        _gambar = new List();
    25    }
    26 
    27    public void Add(Shape s)
    28    {
    29        _gambar.Add(s);
    30    }
    31 
    32    public void Remove(Shape s)
    33    {
    34        _gambar.Remove(s);
    35    }
    36 
    37    public override void Draw(System.Drawing.Graphics g)
    38    {
    39        foreach (Shape s in _gambar)
    40        {
    41            s.Draw(g, _origin);
    42        }
    43    }
    44 
    45    public override void Draw(System.Drawing.Graphics g, Point origin)
    46    {
    47        Point newOrigin = new Point(origin.X + _origin.X,
    48                                    origin.Y + _origin.Y);
    49        foreach (Shape s in _gambar)
    50        {
    51            s.Draw(g, newOrigin);
    52        }
    53    }
    54}
  3. Tambahkan abstract method Draw(Graphics g, Point origin) untuk mengatasi penggambaran Komposisi dimana posisi dari shape nya adalah posisi komposisi ditambah dengan posisi relatif shape tersebut terhadap posisi (0,0) Komposisi.
  4. 1///
    2/// Author: Jeffrey Hermanto Halimsetiawan
    3///
    4public abstract class Shape
    5{
    6    public abstract void Draw(Graphics g);
    7    public abstract void Draw(Graphics g, Point origin);
    8}
  5. Implementasikan method Draw(Graphics g, Point origin) pada Kotak
  6. 01///
    02/// Author: Jeffrey Hermanto Halimsetiawan
    03///
    04public class Kotak : Shape
    05{
    06    private Point _kiriAtas;
    07    private Point _kananBawah;
    08 
    09    public Point KananBawah
    10    {
    11        get
    12        {
    13            return _kananBawah;
    14        }
    15        set
    16        {
    17            _kananBawah = value;
    18        }
    19    }
    20 
    21    public Point KiriAtas
    22    {
    23        get
    24        {
    25            return _kiriAtas;
    26        }
    27        set
    28        {
    29            _kiriAtas = value;
    30        }
    31    }
    32 
    33    public override void Draw(System.Drawing.Graphics g)
    34    {
    35        Draw(g, new Point(0, 0));
    36    }
    37 
    38    public override void Draw(System.Drawing.Graphics g, Point origin)
    39    {
    40        Pen pen = new Pen(new SolidBrush(Color.Brown));
    41 
    42        Point t1 = new Point(origin.X + _kiriAtas.X,
    43                             origin.Y + _kiriAtas.Y);
    44        Point t2 = new Point(origin.X + _kananBawah.X,
    45                             origin.Y + _kananBawah.Y);
    46 
    47        g.DrawRectangle(pen, t1.X,
    48                             t1.Y,
    49                             t2.X - t1.X,
    50                             t2.Y - t1.Y);
    51    }
    52}
  7. Implementasikan method Draw(Graphics g, Point origin) pada Lingkaran
  8. 01///
    02/// Author: Jeffrey Hermanto Halimsetiawan
    03///
    04public class Lingkaran : Shape
    05{
    06    private Point _pusat;
    07    private int _radius;
    08 
    09    public Point Pusat
    10    {
    11        get
    12        {
    13            return _pusat;
    14        }
    15        set
    16        {
    17            _pusat = value;
    18        }
    19    }
    20 
    21    public int Radius
    22    {
    23        get
    24        {
    25            return _radius;
    26        }
    27        set
    28        {
    29            _radius = value;
    30        }
    31    }
    32 
    33    public override void Draw(System.Drawing.Graphics g)
    34    {
    35        Draw(g, new Point(0, 0));
    36    }
    37 
    38    public override void Draw(System.Drawing.Graphics g, Point origin)
    39    {
    40        Pen pen = new Pen(new SolidBrush(Color.DarkGreen));
    41 
    42        Point tp = new Point(origin.X + _pusat.X,
    43                             origin.Y + _pusat.Y);
    44 
    45        g.DrawEllipse(pen, tp.X - _radius,
    46                           tp.Y - _radius,
    47                           _radius * 2,
    48                           _radius * 2);
    49    }
    50}
  9. Implementasikan method Draw(Graphics g, Point origin) pada Garis
  10. 01///
    02/// Author: Jeffrey Hermanto Halimsetiawan
    03///
    04public class Garis : Shape
    05{
    06    private Point _titik1;
    07    private Point _titik2;
    08 
    09    public Point Titik1
    10    {
    11        get
    12        {
    13            return _titik1;
    14        }
    15        set
    16        {
    17            _titik1 = value;
    18        }
    19    }
    20 
    21    public Point Titik2
    22    {
    23        get
    24        {
    25            return _titik2;
    26        }
    27        set
    28        {
    29            _titik2 = value;
    30        }
    31    }
    32 
    33    public override void Draw(System.Drawing.Graphics g)
    34    {
    35        Draw(g, new Point(0, 0));
    36    }
    37 
    38    public override void Draw(System.Drawing.Graphics g, Point origin)
    39    {
    40        Pen pen = new Pen(new SolidBrush(Color.Magenta));
    41 
    42        Point t1 = new Point(origin.X + _titik1.X,
    43                             origin.Y + _titik1.Y);
    44        Point t2 = new Point(origin.X + _titik2.X,
    45                             origin.Y + _titik2.Y);
    46 
    47        g.DrawLine(pen, t1, t2);
    48    }
    49}
  11. Mengubah inisialisasi Shape yang ada pada method InitializeShape() dengan memanfaatkan class Komposisi
  12. 01///
    02/// Author: Jeffrey Hermanto Halimsetiawan
    03/// Untuk melakukan inisialisasi shape yang ada
    04///
    05private void InitializeShape()
    06{
    07    Komposisi kp = new Komposisi();
    08    kp.Origin = new Point(500, 100);
    09 
    10    Kotak k = new Kotak();
    11    k.KiriAtas = new Point(10, 10);
    12    k.KananBawah = new Point(110, 110);
    13    kp.Add(k);
    14 
    15    Lingkaran l = new Lingkaran();
    16    l.Pusat = new Point(60, 60);
    17    l.Radius = 30;
    18    kp.Add(l);
    19 
    20    Garis g = new Garis();
    21    g.Titik1 = new Point(81, 39);
    22    g.Titik2 = new Point(39, 81);
    23    kp.Add(g);
    24 
    25    Komposisi kp2 = new Komposisi();
    26    kp2.Origin = new Point(10, 200);
    27    kp2.Add(k);
    28    kp2.Add(l);
    29    kp2.Add(g);
    30 
    31    _gambar.Add(kp);
    32    _gambar.Add(kp2);
    33 
    34}
Secara umum, class diagram dari program ini adalah sebagai berikut:
Class Diagram Simple Composite
Class Diagram Simple Composite
Output dari program di atas adalah sebagai berikut:
Output Simple Composite
Output Simple Composite
Tentunya, pattern ini akan sangat berguna sekali dalam menyelesaikan permasalahan yang hierarkial.

Adapter Patern

Aspek OO yang didukung : reusability
Kondisi :
Kita mempunyai sebuah class dan sebuah client yang akan menggunakan class tersebut, tetapi tipe class yang akan kita pakai tersebut tidak cocok dengan tipe yang dibutuhkan oleh client*. Yang dimaksud dengan “tipe class tidak cocok “ di sini adalah bahwa class tersebut secara hierarki tidak bisa masuk ke tipe yang dibutuhkan client. (Di akhir tulisan ini disertakan sebuah contoh kasus)
* Sebagai contoh di Java, client di sini dapat berupa sebuah method yang mempunyai parameter bertipe tertentu. Tipe parameter inilah yang tidak sesuai dengan tipe class yang sudah ada.
Tujuan :
Mengubah kontrak dari suatu class sehingga dapat memenuhi kontrak dari client.
Kontrak** di sini adalah behavior yang harus dipunyai oleh suatu class.
**Di Java, kontrak bisa diimplementasikan sebagai interface, abstract class, atau bahkan concrete class. Tapi pada desain yang baik (prefer interface rather than implementation), kontrak biasa diimplementasikan sebagai interface.
Solusi :
Cara untuk mengatasi hal ini cukup mudah, yaitu tinggal membuat sebuah class baru yang memenuhi kontrak dari client.
Implementasi :
Secara intuitif, ada dua pendekatan solusi yang bisa kita lakukan, yaitu dengan inheritance dan dengan composition. Cara yang pertama dikenal sebagai class adapter dan cara kedua dikenal sebagai object adapter.
Sebagai contoh kasus, jika kita sudah punya definisi class sebagai berikut (existing classes).

 1  interface Animal {
 2      public void sleep();
 3  }
 4
 5  class Cat implements Animal {
 6      public void sleep() {
 7          System.out.println("I'm so sleeeepy.. Miauwww");
 8          System.out.println("(Trying to find comfy place to sleep)");
 9          System.out.println("(Find a place, and put its head on its hand)");
10      }
11  }
12
13  class Mouse implements Animal {
14      public void sleep() {
15          System.out.println("Soo sleeepy.. cit cit");
16          System.out.println("(Try to find a hole..)");
17          System.out.println("(Can't find one..creating a new one)");
18          System.out.println("Zzz..zzz.z");
19      }
20  }

Permasalahan : kita harus menggunakan beberapa ekor binatang (Animal) sebagai pemeran (Actor) pada sebuah adegan film (MovieScene), karena skenario film tersebut membutuhkan adegan dimana beberapa ekor binatang akan tidur.

 1  class MovieScene {
 2
 3      private List actorList = new ArrayList();
 4
 5      public void addActor(Actor actor) {
 6          this.actorList.add(actor);
 7      }
 8
 9      public void playScene() {
10          System.out.println("--Begin the scene--");
11
12          Actor actor;
13          for (Iterator iter = actorList.iterator(); iter.hasNext();) {
14              actor = (Actor) iter.next();
15              actor.act();
16          }
17
18          System.out.println("--End fo scene--");
19      }
20
21  }
22
23
24  interface Actor {
25      public void act();
26  }
27
28  class HumanActor implements Actor {
29      public void act() {
30          System.out.println("I'm an human actor and now doing my scenario script...");
31      }
32  }
Kita mempunyai sebuah permasalahan baru, di mana kita harus menggunakan class yang sudah ada sebelumya (Cat) di dalam solusi permasalahan baru kita.
 1  class Movie {
 2      public static void main(String[] args) {
 3          MovieScene scene = new MovieScene();
 4          Actor bruceWillis = new HumanActor();
 5  
 6          scene.addActor(bruceWillis);
 7  
 8          Cat tom = new Cat();
 9          // Animal or Cat can't fit into Actor
10          // so we can't use scene.addActor(Cat cat);
11          // nor write Actor tom = new Cat() here
12          // nor using scene.addActor(Animal a); if we declare tom as an Animal
13  
14          scene.playScene();
15      }
16  }
Untuk mengatasi hal ini, kita mengimplementasikan Adapter pattern, salah satu caranya yaitu dengan membuat sebuah class baru yang meng-implement interface yang dibutuhkan oleh MovieScene.addActor (yaitu Actor), dan menghubungkan method yang dibutuhkan oleh Actor dengan method yang disediakan oleh Animal.

 1  class AnimalActor implements Actor{
 2
 3      private Animal animal;
 4
 5      public AnimalActor(Animal animal){
 6          this.animal = animal;
 7      }
 8
 9      public void act() {
10          animal.sleep();
11      }
12
13  }
Cara yang kedua adalah dengan melakukan composition antara subclass dari ActorAdapter berikut ini dengan Animal, dan meng-override method yang ada dengan pemanggilan method pada Animal.

1  class ActorAdapter implements Actor{
2      public void act() {
3          // do nothing..
4      }
5  }
Sekarang kita bisa menggunakan dua binatang kita untuk ikut serta dalam film.

 1  class MouseActor extends ActorAdapter{
 2    
 3      private Mouse mouse;
 4    
 5      public MouseActor(Mouse mouse){
 6          this.mouse = mouse;
 7      }
 8    
 9      public MouseActor(){
10          mouse.sleep();
11      }
12    
13      public void act() {
14          super.act();
15      }
16  }
17
18
19  class Movie {
20      public static void main(String[] args) {
21          MovieScene scene = new MovieScene();
22          Actor bruceWillis = new HumanActor();
23
24          Cat tom = new Cat();
25          Mouse jerry = new Mouse();
26        
27          Actor adaptedTom = new AnimalActor(tom);
28          Actor adaptedJerry = new MouseActor(jerry);
29        
30          scene.addActor(bruceWillis);
31          scene.addActor(adaptedTom);
32          scene.addActor(adaptedJerry);
33        
34          // suppose that we want to create a new type of Actor and add it to the scene
35          scene.addActor(new ActorAdapter(){
36              public void act() {
37                  System.out.println("Simply do nothing..");
38                  // hey, this looks like how we add an adapter on Swing ;)
39              }
40          });
41        
42          scene.playScene();
43      }
44  }