3.1. Adapter Pattern
Menurut Gang of
Four, Adapter pattern digunakan untuk mengkonversi nama nama fungsi dan nama
agar cocok dengan yang diinginkan oleh client (kelas yang akan menggunakan).
Adapter memungkinkan kelas untuk bisa bekerja bersama sama walaupun sebelum
tidak memungkinkan Karen a perbedaan nama nama fungsi dan variabel.
Class Diagram
Studi Kasus
Misalkan kita telah memiliki sebuah kelas lingkaran
dalam desain aplikasi existing. Pada tahapan berikutnya muncul beberapa kelas
baru yang yang hamper sejenis seperti garis, titik dan segiempat. Garis titik
dan segiempat merupakan mengimplementasikan interface bidang_datar. Garis titik
dan segiempat menshare beberapa fungsi seperti : tampil(), aturwarna(),
sembunyikan(). Ketinya merupakan turunan dari kelas bidangdatar.
Kelas lingkaran merupakan kelas existing yang
sebenarnya bukan turunan dari kelas bidang_datar karena pada saat kelas
lingkaran ini dibuat kelas bidang_datar juga belum ada. Celakanya adalah kelas lingkaran ini telah
memiliki beberapa fungsi yang mirip tetapi namanya lain misal untuk menampilkan
nama fungsinya display(), menyembunyikan hide() dan mengeset warna setcolor()
Pada tahap ini ada 2 solusi yang mungkin bisa
dilakukan :
§ Mengubah
isi kelas lingkaran dengan mengubah kelas lingkaran menjadi turunan dari kelas
bidang_datar dan mengubah nama nama fungsi milik lingkaran sesuai dengan nama
nama fungsi yang telah dideklarasikan di kelas bidang_datar sebagai induknya.
Solusi ini merupakan pilihan yang buruk karena 2 hal pertama karena belum tentu
kita mendapatkan source code kelas lingkaran. Kedua karena mengunah kode
program selalu menghasilkan error baru, ingat bahwa kelas lingkaran adalah
kelas eksisting yang barangkali sudah ada kelas lain yang menginstansiasi dan
memanggil fungsi fungsi asli milik kelas ini sehingga ketika diganti mungkin
akan menimbulkan error di berbagai tempat lain kode program kita.
§ Membuat
sebuah kelas baru yang merupakan implementasi dari kelas bidang_datar, kelas
ini dapat mewakili kelas lingkaran misalkan diberi nama lingkaran_new.
Lingkaran_new sebagai turunan dari kelas bidang_datar akan mewarisi semua
fungsi milik bidang_datar yaitu : tampil(), aturwarna() dan sembunyikan(). Agar kelas ini dapat memanfaatkan semua
resource (kode program) yang telah ada di kelas lingkaran asli (existing) maka
di buat kelas ini memiliki salah satu atribut yang bertipe lingkaran. Isi
fungsi tampil adalah mengeksekusi fungsi display milik kelas lingkaran yang
asli demikian juga dengan fungsi fungsi yang lain.
Perhatikan desain di bawah ini :
Solusi menggunakan adapter pattern :
Contoh Program dalam C#:
public class main {
private bidang_datar mbidang_datar;
public main () {
mbidang_datar = new Adapter();
mbidang_datar.setwarna();
mbidang_datar.tampil();
mbidang_datar.sembunyi();
mbidang_datar = new segi4();
mbidang_datar.setwarna();
mbidang_datar.tampil();
mbidang_datar.sembunyi();
}
}
public class lingkaran {
public
lingkaran () {
}
public
void display () {
}
public
void setcolor () {
}
public
void hide () {
}
public
void specificRequest () {
}
}
public class Adapter implements bidang_datar {
private
lingkaran mlingkaran;
public
void request () {
}
public
void tampil () {
mlingkaran.display();
}
public
void sembunyi () {
mlingkaran.hide();
}
public
void setwarna () {
mlingkaran.setcolor();
}
}
3.2.
Bridge Pattern
Bridge Pattern merupakan pattern
yang kuat (powerfull) dan sering digunakan dalam pengembangan. Dan ini sebanding
dengan usaha untuk mempelajarinya yang cukup menantang. Untuk memahami design
pattern yang satu ini, kita perlu melihat makna decouple (tidak berpasangan),
abstraction (abstraksi), dan implementation (implementasi) dari sisi yang
berbeda terlebih dahulu. Decouple adalah bagaimana objek tidak terhubung satu
sama lain, berdiri sendiri (independent), terpisah. Abstraksi adalah konsep
bagaimana antar objek saling terhubung. Sedangkan “implementasi” janganlah
dipandang sebagai penurunan dari suatu kelas abstrak (concrete class).
Pandanglah “implementasi” sebagai objek lain yang digunakan oleh kelas abstrak
(dan turunannya) untuk mengimplementasi dirinya (untuk kelas abstrak). Dalam
sebagian besar tutorial, bridge pattern didefinisikan sebagai pattern yang berusaha
memisahkan antara abstraksi dan implementasi.
Pola bridge berlaku ketika ada
kebutuhan untuk menghindari mengikat permanen antara abstraksi dan sebuah
implementasi dan ketika abstraksi dan implementasi perlu bervariasi secara
independen. Menggunakan
pola jembatan akan meninggalkan kode klien tidak berubah dengan tidak perlu
mengkompilasi ulang kode.
Maksud dari pola ini
adalah untuk memisahkan abstraksi dari implementasi sehingga dua dapat bervariasi secara independen. Diagram UML
kelas untuk Pola Bridge:
Class
peserta dalam pola bridge
adalah:
1. Abstraksi - Abstraksi
mendefinisikan antarmuka abstraksi.
2. AbstractionImpl -
Mengimplementasikan interface abstraksi menggunakan referensi ke obyek
Implementor jenis.
3. Pelaksana - Implementor
mendefinisikan antarmuka untuk kelas implementasi. Interface ini tidak perlu
sesuai langsung ke antarmuka abstraksi dan bisa sangat berbeda. Imp abstraksi menyediakan
implementasi dalam hal operasi yang disediakan oleh antarmuka Implementor.
4. ConcreteImplementor1,
ConcreteImplementor2
- Mengimplementasikan interface Implementor.
Contoh code dalam Java:
class Node {
public int value;
public Node prev, next;
public Node( int i ) { value = i; }
}
class StackArray {
private int[] items = new int[12];
private int total = -1;
public void push( int i ) { if ( ! isFull()) items[++total] = i; }
public boolean isEmpty() { return total == -1; }
public boolean isFull() { return total == 11; }
public int top() {
if (isEmpty()) return -1;
return items[total];
}
public int pop() {
if (isEmpty()) return -1;
return items[total--];
} }
class StackList {
private Node last;
public void push( int i ) {
if (last == null)
last = new Node( i );
else {
last.next = new Node( i );
last.next.prev = last;
last = last.next;
} }
public boolean isEmpty() { return last == null; }
public boolean isFull() { return false; }
public int top() {
if (isEmpty()) return -1;
return last.value;
}
public int pop() {
if (isEmpty()) return -1;
int ret = last.value;
last = last.prev;
return ret;
} }
class StackFIFO extends StackArray {
private StackArray temp = new StackArray();
public int pop() {
while ( ! isEmpty())
temp.push( super.pop() );
int ret = temp.pop();
while ( ! temp.isEmpty())
push( temp.pop() );
return ret;
} }
class StackHanoi extends StackArray {
private int totalRejected = 0;
public int reportRejected() { return totalRejected; }
public void push( int in ) {
if ( ! isEmpty() && in > top())
totalRejected++;
else super.push( in );
} }
class BridgeDisc {
public static void main( String[] args ) {
StackArray[] stacks = { new StackArray(), new StackFIFO(), new StackHanoi() };
StackList stack2 = new StackList();
for (int i=1, num; i < 15; i++) {
stacks[0].push( i );
stack2.push( i );
stacks[1].push( i );
}
java.util.Random rn = new java.util.Random();
for (int i=1, num; i < 15; i++)
stacks[2].push( rn.nextInt(20) );
while ( ! stacks[0].isEmpty())
System.out.print( stacks[0].pop() + " " );
System.out.println();
while ( ! stack2.isEmpty())
System.out.print( stack2.pop() + " " );
System.out.println();
while ( ! stacks[1].isEmpty())
System.out.print( stacks[1].pop() + " " );
System.out.println();
while ( ! stacks[2].isEmpty())
System.out.print( stacks[2].pop() + " " );
System.out.println();
System.out.println( "total rejected is "
+ ((StackHanoi)stacks[2]).reportRejected() );
} }
Hasil Compiling :
public int value;
public Node prev, next;
public Node( int i ) { value = i; }
}
class StackArray {
private int[] items = new int[12];
private int total = -1;
public void push( int i ) { if ( ! isFull()) items[++total] = i; }
public boolean isEmpty() { return total == -1; }
public boolean isFull() { return total == 11; }
public int top() {
if (isEmpty()) return -1;
return items[total];
}
public int pop() {
if (isEmpty()) return -1;
return items[total--];
} }
class StackList {
private Node last;
public void push( int i ) {
if (last == null)
last = new Node( i );
else {
last.next = new Node( i );
last.next.prev = last;
last = last.next;
} }
public boolean isEmpty() { return last == null; }
public boolean isFull() { return false; }
public int top() {
if (isEmpty()) return -1;
return last.value;
}
public int pop() {
if (isEmpty()) return -1;
int ret = last.value;
last = last.prev;
return ret;
} }
class StackFIFO extends StackArray {
private StackArray temp = new StackArray();
public int pop() {
while ( ! isEmpty())
temp.push( super.pop() );
int ret = temp.pop();
while ( ! temp.isEmpty())
push( temp.pop() );
return ret;
} }
class StackHanoi extends StackArray {
private int totalRejected = 0;
public int reportRejected() { return totalRejected; }
public void push( int in ) {
if ( ! isEmpty() && in > top())
totalRejected++;
else super.push( in );
} }
class BridgeDisc {
public static void main( String[] args ) {
StackArray[] stacks = { new StackArray(), new StackFIFO(), new StackHanoi() };
StackList stack2 = new StackList();
for (int i=1, num; i < 15; i++) {
stacks[0].push( i );
stack2.push( i );
stacks[1].push( i );
}
java.util.Random rn = new java.util.Random();
for (int i=1, num; i < 15; i++)
stacks[2].push( rn.nextInt(20) );
while ( ! stacks[0].isEmpty())
System.out.print( stacks[0].pop() + " " );
System.out.println();
while ( ! stack2.isEmpty())
System.out.print( stack2.pop() + " " );
System.out.println();
while ( ! stacks[1].isEmpty())
System.out.print( stacks[1].pop() + " " );
System.out.println();
while ( ! stacks[2].isEmpty())
System.out.print( stacks[2].pop() + " " );
System.out.println();
System.out.println( "total rejected is "
+ ((StackHanoi)stacks[2]).reportRejected() );
} }
Hasil Compiling :
3.3. Composite pattern
Composit Pattern adalah saat satu
object yang merupakan sebuah collection, yang isinya antara lain adalah object-
object yang collection juga, dan mempunyai sifat yang sama dengan si parent
tadi. jadi terjadi proses rekursif disini. Keuntungannya: kita bisa
memperlakukan keseluruhan collection seakan- akan sebagai satu object saja. 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.
Dalam pemrograman, komposit digunakan ketika
berhadapan dengan struktur pohon. Hal ini sendiri adalah cukup sebuah
konsep abstrak. Salah satu contoh komposit yang Anda lihat sehari-hari adalah sistem
menu, dimana menu bar memiliki menu memiliki menu banyak, yang sendiri dapat
memiliki submenu. Apa pun yang dapat dimodelkan sebagai struktur pohon dapat dianggap
sebagai contoh komposit, seperti bagan organisasi.
Pola KompositKomposit ini dikenal sebagai pola struktural, karena itu digunakan untuk membentuk struktur objek besar di seluruh objek yang berbeda banyak. Definisi Komposit disediakan Gang of Four buku tentang Desain Pola menyatakan: Memungkinkan Anda untuk menyusun objek ke dalam struktur pohon untuk mewakili bagian-keseluruhan hirarki. Komposit memungkinkan klien memperlakukan objek
Dalam bentuk yang paling
sederhana, kita bisa memikirkan komposit
sebagai koleksi benda-benda, di mana salah satu dari benda itu
sendiri bisa menjadi komposit, atau benda sederhana.
Mari kita lihat definisi diagram
sebelum kita pergi ke lebih rinci. Antarmuka Komponen mendefinisikan antarmuka bahwa semua benda dalam sistem terdiri perlu menggunakan, apakah mereka daun (obyek sederhana)
atau komposisi. Namun, hal ini biasanya diimplementasikan
sebagai kelas abstrak menyediakan
beberapa perilaku default dari
pengaya,
keluarkan dan metode getChild.
Daun tidak memiliki anak, dan sebagai kebutuhan-satunya untuk menerapkan metode operasi. Komposit perlu berbuat lebih banyak, karena juga mengandung komponen. Komposit akan lebih dari mungkin perlu untuk mengimplementasikan metode operasi, yang dianggap sebagai operasi Daun terkait. Kadang-kadang ini mungkin tidak masuk akal untuk komposit untuk diterapkan. Biasanya, Komposit akan menerapkan metode dengan mendelegasikan kepada anak-anak. Klien hanya menggunakan antarmuka Komponen untuk memanipulasi objek.
Daun tidak memiliki anak, dan sebagai kebutuhan-satunya untuk menerapkan metode operasi. Komposit perlu berbuat lebih banyak, karena juga mengandung komponen. Komposit akan lebih dari mungkin perlu untuk mengimplementasikan metode operasi, yang dianggap sebagai operasi Daun terkait. Kadang-kadang ini mungkin tidak masuk akal untuk komposit untuk diterapkan. Biasanya, Komposit akan menerapkan metode dengan mendelegasikan kepada anak-anak. Klien hanya menggunakan antarmuka Komponen untuk memanipulasi objek.
Pola ini harus
digunakan bila Anda ingin mewakili objek secara hierachical,
atau Anda perlu objek dan komposit untuk
diperlakukan secara seragam. Kerangka grafis adalah penggunaan paling umum dari pola ini. Objek dasar Grafis menyediakan
kelas dasar untuk semua objek grafis lainnya, seperti Line, Rectangle,
yang menyediakan implementasi sendiri dari cat () / gambar () method. Pola
Komposit sering digunakan untuk representasi pohon sintaks abstrak.
Contoh Code Komposit dalam java:
//Component interface
public interface
Graphic
{
public void
add(Graphic
g);
public void
remove(Graphic
g);
public Graphic get(int
index);
public void
paint();
}
Berikutnya, kita akan mengimplementasikan interface ini untuk objek CompositeGraphic. Titik kunci untuk dicatat di sini adalah bahwa itu cat delegasi
metode lukisan dengan
objek anak:
//Composite
public class
CompositeGraphic
implements Graphic
{
private
List<Graphic>
children = new ArrayList<Graphic>();
public void
paint()
{
//run the paint operation for each
child
for(Graphic g: children)
{
g.paint();
}
}
public void
add(Graphic
g)
{
children.add(g);
}
public void
remove(Graphic
g)
{
if(children.contains(g))
{
children.remove(g);
}
}
public Graphic get(int
index)
{
if(index < children.size())
{
return children.get(index);
}
}
Daun, dalam hal ini SimpleGraphic kasus, tidak dapat berisi grafik lain, sehingga tidak perlu untuk mengimplementasikan operasi list.
Yang paling penting ini adalah bahwa ia menyediakan implementasi konkret dari cat () metode:
//Leaf
public class
SimpleGraphic
implements Graphic
{
public void
paint()
{
//run the paint operation
}
/**
* Because we have no children, these
operations will do nothing
**/
public void
add(Graphic
g)
{
//unsupported operation
}
public void
remove(Graphic
g)
{
//unsupported operation
}
public void
get(int
index)
{
//unsupported operation
}
Tidak ada komentar:
Posting Komentar