Pages

Selasa, 10 Juli 2012

Adapter Pattern

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  }

0 komentar:

Posting Komentar