Adapter Pattern

將類別的介面轉換成另一個介面,使得原本不相容的類別可以互相一起工作。

使用的情況多半是在現有的介面無法滿足需求,必須轉接物件來完成功能,其實還可以用在封裝 unfinished class。
 
Description:
你需要未完成類別(unfinished class)的功能,由於該類別還未完成,你只能先建立dummy class 來滿足需求,可使用Adapter來封裝dummy class,
讓被影響的部份降至最低。
假設有個Person類別,該類別是由其他人來實作,但由於一些狀況目前還無法完成Person類別,不過現在你就需要從Person取得String name和int age,
首先建立DummyPerson,其中只實作需要的方法,如下

package com.foxx.person.adapter;
public class DummyPerson
{
    public String getName(){
        return "John";
    }
    public int getAge(){
        return 20;
    }
}

如果不用Adapter來封裝DummyPerson,也可以直接使用DummyPerson,但有個很大的缺點,
當你在10個位置使用DummyPerson,也代表將來Person完成後,你必須在這10個位置更換Person來取代DummyPerson,
需要修改的位置越多,出錯的機率也越大。使用Adapter來封裝DummyPerson就可限制修改的範圍只在Adapter中。
 
建立PersonAdapter類別

package com.foxx.person.adapter;
public class PersonAdapter
{
    private DummyPerson mPerson = new DummyPerson();
    public String getName(){
        return mPerson.getName();
    }
    public int getAge(){
        return mPerson.getAge();
    }
}

其中會有DummyPerson型態的類別成員,而getName以及getAge方法則委託給DummyPerson來完成
 
Client端呼叫

package com.foxx.person.adapter;
public class Client
{
    public void showPersonData(){
        PersonAdapter personAdapter = new PersonAdapter();
        System.out.println(personAdapter.getName());
        System.out.println(personAdapter.getAge());
    }
}

可以看到這裡只呼叫PersonAdapter的方法,Client並不知道回傳值是誰提供的。在Person類別未完成之前,都使用PersonAdapter來提供需要的功能
 
OK~ 現在Person類別完成了,如下

package com.foxx.person.adapter;
public class Person
{
    private String mName;
    private int mAge;
    public Person(String name, int age) {
        mName = name;
        mAge = age;
    }
    public String getName()
    {
        return mName;
    }
    public int getAge()
    {
        return mAge;
    }
}

 
現在只要修改PersonAdapter即可,不必更動到客戶端。

package com.foxx.person.adapter;
public class PersonAdapter
{
    private Person mPerson;
    public PersonAdapter(){
        mPerson = new Person("John",20);
    }
    public String getName(){
        return mPerson.getName();
    }
    public int getAge(){
        return mPerson.getAge();
    }
}