iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 12
1
自我挑戰組

初探設計模式系列 第 12

[ Day 12 ] 隨心所欲地重用不相容的類別~ - 轉接器模式 ( Adapter Pattern )

前言

昨天出差今天早上申請出差相關事宜...

跑流程弄文件弄了一個小時還沒有弄好QQ,

大公司的流程真的很複雜,

之前出差比較近的像去桃園之類的就自己吃下了,

這次搭高鐵不申請不划算,但是跑流程真的很麻煩啊Orz。

定義

In software engineering, the adapter pattern is a software design pattern (also known as wrapper, an alternative naming shared with the decorator pattern) that allows the interface of an existing class to be used as another interface.[1] It is often used to make existing classes work with others without modifying their source code.

-- from wikipedia Adapter pattern


在軟體工程中,轉接器模式是一種設計模式(有時也被稱為wrapper或裝飾模式),用一個介面來轉換另一個已存在的類別。這是經常被使用來用一個已存在的類別,用一個介面來包裝已存在類別使兩個不相容的類別可以共同工作。

在很多情況下我們所獲得的資料,並不是我們要直接呈現的資料,所以需要經過某些轉換。可能是在呈現資料的需求之下,需要實踐與資料來源不同的functions,在這種狀況之下,如果我們不想要改動到兩者的程式碼,那可以用轉接器模式 ( Adapter pattern )。

解決的問題

轉接器模式主要是要解決一個既定的類別但是:

  • 並沒有一個適合的介面我們可以重用。
  • 提供的介面跟我們的介面不相容。

在現實生活中有很像的例子,例如USB TypeC -> vga的轉接器。

主要的角色有客戶端(Client)轉接的介面(Target)、介面的實作(Adapter)提供的類別(Adaptee)

類別圖

Client端有一個私有的adapter(實作)為了來實踐它想要做的事情,

另外每個Adapter有一個私有的Adaptee(被轉換的類別)。

![Adapter Pattern](/Users/orcarex/Desktop/2019鐵人賽 - 初探設計模式/[ Day 12 ] Adapter Pattern.png)

試著實踐一下轉接器模式:

有一個黑人我想要重用他的名字

public class BlackMan {
    String name;

    public BlackMan(String name){
        this.name = name;
    }

    public void helloEnglish(){
        System.out.println("yo~ what's up!! niga~");
    }

    public void selfIntroEnglish(){
        System.out.println("hello, I living in taipei. " +
                "my name is " + this.name + ".");
    }

}

介面

public abstract class People {
    String name;

    public People(String name){
        this.name = name;
    }

    public abstract void hello();

    public abstract void selfIntro();

    public String getName() {
        return name;
    }
}

介面的實踐

public class BlackmanTranslator extends People{


    public BlackmanTranslator(String name) {
        super(name);
    }


    @Override
    public void hello() {
        System.out.println(getName() + ":哩甲霸咩~真的假的!?");
    }

    @Override
    public void selfIntro() {
        System.out.println("大家好我是" + getName() +
                ",現在台北工作。");
    }
}

利用被翻譯出來的介面

public class TaiwanMan {
    private People people;

    public TaiwanMan(People people){
        this.people = people;
    }

    public void hello(){
        people.hello();
    }

    public void selfIntro(){
        people.selfIntro();
    }

}

測試一下

public class Test {
    @org.junit.jupiter.api.Test
    public void test(){

        BlackMan blackMan = new BlackMan("black");

        blackMan.helloEnglish();
        blackMan.selfIntroEnglish();


        TaiwanMan taiwanMan = new TaiwanMan(new BlackmanTranslator(blackMan.name));

        taiwanMan.hello();
        taiwanMan.selfIntro();

    }
}

測試的結果

yo~ what's up!! niga~
hello, I living in taipei. my name is black.
black:哩甲霸咩~真的假的!?
大家好我是black,現在台北工作。

成功利用Adapter pattern來重新利用黑人的名字,
當然現實開發中不會只為了重新利用一個變數而使用轉接器模式,
可以根據自己的狀況來判斷來選擇要用哪一種方式開發會比較適合。

如果有什麼意見或是我寫的有什麼不完善的地方,歡迎留言或私訊我,今天就先介紹到這邊了~感恩。


上一篇
[ Day 11 ] 老闆這這樣說~你照著做就對了 - 範本方法模式 ( TemplateMethod Pattern )
下一篇
[ Day 13 ] 自己不會沒關係~找一個代理人幫忙處理 - 代理模式 ( Proxy Pattern )
系列文
初探設計模式30

尚未有邦友留言

立即登入留言