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.

Rabu, 16 Maret 2016

[Yii Framework] Mudah Memainkan Database Anda dengan Active Record

Pada Yii Framework dikenal Active Record yang digunakan untuk mempermudah aplikasi berinteraksi dengan database. Yii sendiri sudah cukup jelas memaparkan penggunaan active record pada Yii Framework disini. Tapi saya akan ulas kembali lebih detail beberapa hal terkait cara penggunaan Yii Framework sendiri pada sebuah aplikasi. Saya sendiri akan membahas beberapa active record yang sangat sering saya gunakan dalam pembuatan aplikasi, diantaranya sebagai berikut:
Misal saya memiliki sebuah database dengan tabel “biodata”. Tabel “biodata” sendiri memiliki attribute sebagai berikut:
  1. id : Primary Key, Integer, Auto Increment
  2. nama : varchar(100)
  3. alamat : text il
Tabel tersebut saya input data seperti berikut:
             |   id    |     nama         | alamat                    |
             |    1     |   Joko            | Palembang           |
             |    2    |    Ali                | Jakarta                  |
             |    3    |     Joko           | Papua                     |
             |     4    |   Mahmud    |  Palembang          |
             |     5    |   Ga tahu       | Ga tahu juga        |
  • FindByPk() : Digunakan untuk menemukan data yang memiliki Primary Key tertentu.
contoh penggunaan :
$itu=Biodata::model()->findByPk(2);
Code di atas akan mengembalikan sebuah nilai dari tabel biodata yang memiliki “id” 2. Untuk menampilkan hasil nya, anda dapat gunakan code seperti berikut:
echo $itu->id; (untuk menampilkan id nya)
echo $itu->nama; (untuk menampilkan nama nya)
echo $itu->alamat; (untuk menampilkan alamatnya)
  • FindByAttributes(): Digunakan untuk menemukan data yang memiliki attribute tertentu.
contoh penggunaan :
$itu=Biodata::model()->findByAttributes(array('nama'=>'Ali')); atau bisa juga
$itu=Biodata::model()->findByAttributes(array('nama'=>'Joko','alamat'=>'Palembang'));
Sedangkan tata cara untuk menampilkannya sama saja dengan yang digunakan pada ‘findByPk()’

  • FindAllByAttributes() : Digunakan untuk menemukan data yang memiliki attribute tertentu, tapi data yang di hasilkan lebih dari 1 row data.
contoh penggunaan :
$itu=Biodata::model()->findAllByAttributes(array('nama'=>'Joko'));
Dari code di atas, akan dihasilkan 2 buah row data. Yaitu data dengan ‘id’ 1 dan 3, itu karena kedua nya memiliki ‘nama’ Joko. Karena data yang dihasilkan lebih dari 1, maka cara menampilkannya pun harus 1 per 1. Berikut tata cara untuk menampilkan data nya:
foreach($itu as $i=>$ii)
{
      echo $ii->id;
      echo $ii->nama;
      echo $ii->alamat;
}

  • Menggunakan ‘scopes’
Penggunaan scopes digunakan saat kita membutuhkan sebuah query yang sama berulang-ulang pada suatu aplikasi. Hal ini dimaksud untuk mempermudah dan mempersingkat aktivitas coding kita :D. Contoh penggunaan :
    public function scopes()
    {
        return array(
            'panggilJoko'=>array(
                'condition'=>'nama=Joko',
                'limit'=>5,
            ),
        );
    }
Letakkan kode di atas pada “model” bersangkutan. Kode tersebut jika dipanggil akan menghasilkan semua data dengan nama “Joko” dimana maksimal yang di tampilkan adalah 5 buah data. Berikut contoh code untuk menggunakan fungsi tersebut dan menampilkan data yang dihasilkan dari fungsi tersebut :
$itu=Biodata::model()->panggilJoko()->findAll();
//berikut untuk menampilkan nya
foreach($itu as $i=>$ii)
{
      echo $ii->id;
      echo $ii->nama;
      echo $ii->alamat;
}
  • Menggunakan ‘scopes’ dengan parameter
Pada fungsi yang ada di atas, kita memanggil sebuh query yang sudah kita tetapkan kondisi nya. Misal ‘nama=Joko’, bagaimana bila kita ingin membuat banyak kondisi dimana nama nya bisa kita ubah-ubah setiap saat kita memanggil fungsi tersebut. Tentu kita harus mengubah fungsi tersebut menjadi dinamis dengan cara memberikan parameter pada fungsi tersebut. Berikut cara untuk menggunakannya:
Masukkan code berikut pada ‘model’ bersangkutan:
public function panggilSiapa($nama=Joko)
{
    $this->getDbCriteria()->mergeWith(array(
        'condition'=>'nama='.$nama,
        'limit'=>4,
    ));
    return $this;
}
Kode di atas akan mengembalikan semua data pada tabel biodata yang memiliki nama sesuai dengan kita mau. Tapi bila kita tidak mengisi parameter nama sesuai yang dimaksud, maka code tersebut akan menghasilkan data yang memiliki nama “Joko”(default nya adalah “Joko”). Berikut cara menggunakan fungsi tersebut beserta cara menampilkannya:
$itu=Biodata::model()->panggilSiapa()->findAll(); //mengembalikan semua data dengan nama Joko
$itu=Biodata::model()->panggilSiapa('Ali')->findAll();  //mengembalikan semua data dengan nama Ali
Sedangkan cara menampilkan data nya adalah sebagai berikut:
foreach($itu as $i=>$ii)
{
      echo $ii->id;
      echo $ii->nama;
      echo $ii->alamat;
}
Sebenarnya masih ada banyak Active Record yang tidak saya paparkan 1 per 1 disini, seperti findBySql,findAllBySql, dll.. Anda dapat menggali sendiri penggunaan lainnya. Tapi 1 hal yang perlu anda ingat,
Penggunaan Active Record lebih lambat dari menggunakan SQL query secara langsung ke database. Hal ini sudah dijelaskan langsung dari Yii Framework disini.
Jadi tentukan kebutuhan anda sendiri kapan anda harus menggunakannya atau tidak…
Selamat mencoba…
Semoga membantu…. :D

Rabu, 15 April 2015



Rabu, 07 Mei 2014

Aplikasi Untuk Broadcast Email & Delayed Shutdown

Salam sejahtera penduduk, dah lama gag posting artikel kali ini saya mau share 2 softwere sederhana buatan saya sendiri yaitu aplikasi kirim email dan delayed shutdown,,mudah2han bisa berguna bagi agan2 aplikasi kirim email disini selain untuk kirim juga dapat di gunakan untuk membroadcast email kesemua kontak yang ada di database...........
Untuk pembuatan saya menggunakan c# dan acces database
berikut screen shutnya

untuk login harus gmail yang masih berlaku gan

link download klik disini


dan yang ke dua delayed shutdown berfungsi untuk mentimer kapan pc/lepi kita ingin di matikan,lumayan gan daripada ketiduran dan pc masih nyala kan kasihan hehe dob
screenshut

link download klik disini

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.