iT邦幫忙

2023 iThome 鐵人賽

DAY 24
0
自我挑戰組

深入淺出設計模式 (Head First Design Pattern) - 重點整理及範例分享系列 第 24

[深入淺出設計模式] Ch7 The Adapter Pattern (1) - 【轉接器模式】範例 SimUDuck 鴨子模擬器

  • 分享至 

  • xImage
  •  

轉接器模式 Adapter Pattern

可以讓物件在不同類別或介面中被使用,它可以把物件在不改變它本身類別的情況下,讓它轉換成另一個類別的樣子。
轉接器可以分成兩種:

  1. Object Adapter: 把轉換器定義成想要轉換成的目標類別
  2. Class Adapter: 運用多重繼承,讓一個類別繼承多個類別,就可以被當成其他類別使用(Java沒辦法用多重繼承,C++可以)

Object Adapter 範例 SimUDuck 鴨子模擬器 - Duck Pond

第一章有做過鴨子模擬器,這次就以同一個概念來當範例,假設模擬器的池塘附近,除了鴨子還會有火雞 WildTurkey() (?)

public abstract class Duck {
    protected String name;
   
    public abstract void fly();
    public abstract void makeSound();
}

public class MallardDuck extends Duck{
    public MallardDuck(String name){
        this.name = name;
    }

    public void fly(){
        System.out.println("I'm flying.");
    }

    public void makeSound(){        
        System.out.println(name + ": quack quack quack");
    }
}

public abstract class Turkey {
    protected String name;
   
    public abstract void gobble(); 
    public abstract void fly();
}

public class WildTurkey extends Turkey{
    public WildTurkey(String name){
        this.name = name;
    }

    public void gobble() {
        System.out.println(name + ": Gobble gobble"); 
    }

    public void fly() {
        System.out.println("I’m flying a short distance");
    }
}

但是池塘裡只能有鴨子的子類別鴨子們,例如 MallardDuck():

public class Pond {
    ArrayList<Duck> ducks;

    public Pond(){
        ducks = new ArrayList<Duck>(5);
    }

    public void setDuck(Duck duck){
        ducks.add(duck);
    }

    public void duckGreet(){
        for(int i = 0; i < ducks.size(); i++){
            System.out.print(i + ". ");
            ducks.get(i).makeSound();
        }
    }
}

這時候可以用轉接器模式,把火雞轉成鴨子的類別:

public class DuckAdapter extends Duck{
    public Turkey turkey;
    
    //建構子可以看出,並沒有改變物件是火雞的本質,只是以不同方式實現
    public DuckAdapter(Turkey turkey){
        this.turkey = turkey;
    }

    public void makeSound(){
        turkey.gobble();
    }

    public void fly(){
        turkey.fly();
    }
}

測試看看

public class DuckSimulator {
   
    public static void main(String[] args) {
        Duck Felix = new MallardDuck("Felix");
        Duck Larry = new MallardDuck("Larry");
        Pond duckPond = new Pond();
        
        //Roger本質上是 WildTurkey(), 但為了讓他跟鴨子待在池塘,要把它轉成鴨子
        DuckAdapter Roger = new DuckAdapter(new WildTurkey("Roger"));
        duckPond.setDuck(Felix);
        duckPond.setDuck(Larry);
        duckPond.setDuck(Roger);
        duckPond.duckGreet();
    }
}

輸出:

https://ithelp.ithome.com.tw/upload/images/20231009/20163178wEjxIUEA19.png


參考資料:

  1. https://programming.im.ncnu.edu.tw/J_Chapter4.htm
  2. 《深入淺出設計模式 (Head First Design Patterns) 》

Disclaimer
因為讀的是原文版,所以難免會有翻譯詞不達意或是專有名詞上的差異,有錯誤的話歡迎在留言區一起交流!


上一篇
[深入淺出設計模式] Ch6 The Command Pattern (4) - 【Meta Command Pattern】範例實作
下一篇
[深入淺出設計模式] Ch7 The Adapter Pattern (2) - 【轉接器模式】Class Adapter範例 PlugAdapter 插頭轉接
系列文
深入淺出設計模式 (Head First Design Pattern) - 重點整理及範例分享35
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言