假如要使用A, 但無法直接使用, 只能使用B介面
所以我們用轉接器類別包裝A的方法,並且實作B,達到轉接的效果
用螢幕轉接器的例子直接解釋
例如我們有個 HDMI的線, 叫做 HDMI interface
1 2 3 4 5
| interface HDMI { boolean connect(String device); }
|
但現在有個螢幕只有支援VGA的插孔
所以我們需要個 HDMI轉VGA的Adaptor類別, 把VGA的類別引入進來, 並使用之
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class HdmiToVgaAdpator implements HDMI { VGA vgaCable = null;
HdmiToVgaAdpator(VGA vgaCable) { this.vgaCable = vgaCable; }
public boolean connect(String device) { System.out.println("使用轉接器的connect功能!"); vgaCable.connect(device); return true; } }
|
因為有使用到VGA類別, 所以來定義一下
1 2 3 4 5 6 7 8 9 10 11 12
| interface VGA { boolean connect(String device); }
class VGACable implements VGA { public boolean connect(String device) { System.out.println("VGA線連接: " + device); return true; } }
|
來定義有台筆電, 是只有具備hdmi孔, 但具備著可以連接到某裝置進行投影
1 2 3 4 5 6 7
| class Labtop { public void connectToDevice(HDMI hdmi, String device) { System.out.println("筆電只有hdmi孔, 使用實作hdmi介面的 'hdmi轉vga的轉接器' 類別!"); hdmi.connect(device); } }
|
接著來使用吧
1 2 3 4 5 6 7 8 9 10 11
| public class main { public static void main(String[] args) {
Labtop laptop = new Labtop(); laptop.connectToDevice( new HdmiToVgaAdpator( new VGACable()), "老舊投影機"); } }
|
我們可以看到結果為:
- 筆電使用了 實作hdmi介面的轉接器 (轉接器因為實作了hdmi interface, 所以可以插入筆電的hdmi孔)
- 接著轉接器引入了VGA cable類別, 故轉接器就可以使用VGA的connect()功能
- 最後就觸發VGA功能, 與投影裝置連動
實際應用場景
通常轉接器模式可用在轉接那些已經過時的模組&方法
例如有模組是用Java較舊迭代Collection的版本去寫的, 為Enumeration Interface
但現在新的專案中,是使用Iterator方式去迭代Collection
1 2 3 4 5 6 7 8 9 10
| class NewLoopService { public void loopCollection(Collection col, Iterator itr) { itr = col.iterator(); while(itr.hasNext()) { System.out.println(itr.next()); } } }
|
使用NewLoopService
1 2 3 4 5 6 7 8 9 10 11 12 13
| class main() { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("apple"); list.add("banana"); Iterator itr; NewLoopService loopService = new NewLoopService(); loopService.loopCollection(list, itr); } }
|
但現在若只能用舊版的 Enumeration
方式去迭代
這時就可以寫一個 EnumeratorAdaptor
來實作可兼容Iterator
的類別, 並可呼叫 Enumeration
的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class EnumeratorAdaptor<E> implement Iterator { Enumeration<E> enumeration; EnumeratorAdaptor(Enumeration<E> enumeration) { this.enumeration = enumeration; } public boolean hasNext() { return this.enumeration.hasMoreElements(); } public Object next() { return this.enumeration.nextElement(); } public void remove() { throw new UnsupportedOperationException(); } }
|
這時我們可以在main()
中改用轉接器, 來間接使用Enumeration了!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| class main() { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("apple"); list.add("banana"); EnumeratorAdaptor itr; NewLoopService loopService = new NewLoopService(); loopService.loopCollection(list, itr); } }
class NewLoopService { public void loopCollection(Collection col, Iterator itr) { itr = col.iterator(); while(itr.hasNext()) { System.out.println(itr.next()); } } }
|
透過以上方法, 可以把要使用Enumeration方式的service, 但該Service又是只能吃Iterator的輸入, 那就可以實作一個 EnumeratorAdaptor
, 帶入Service, 並透過轉接器使用 Enumeration的方式去撈出Collection內容.