package adapter; /**目標角色 Target 接口 * 香港地區使用的插座面板,提供輸出電流的功能 * @author noteless * */ public interface TargetHongkongPanelInterface { public void offerHongKongElectricity(); } package adapter; /**目標角色 Target 某個具體的港版插座面板 實現類 * 香港地區使用的插座面板,提供輸出電流的功能 * @author noteless * */ public class TargetHongkongPanel implements TargetHongkongPanelInterface{ @Override public void offerHongKongElectricity() { System.out.println("港版面板 提供電流"); } }
大陸地區插座面板java
package adapter; /**被適配角色 Adaptee 接口 * 大陸地區使用的插座面板,提供輸出電流的功能 * @author noteless * */ public interface AdapteeChinaMainlandPanelInterface { public void offerChinaMainlandElectricity(); } package adapter; /**被適配角色 Adaptee 某種具體類型的插座面板 實現類 * 大陸地區使用的插座面板,提供輸出電流的功能 * @author noteless */ public class AdapteeChinaMainlandPanel implements AdapteeChinaMainlandPanelInterface{ @Override public void offerChinaMainlandElectricity() { System.out.println("國標面板 提供電流"); } }
package adapter; /**客戶角色 Client 港版插頭 * @author noteless * */ public class ClientHongKongSocket { /**接受港版插座面板做爲參數 * 港版插頭,插入到港版插座面板 * @param targetHongkongPanel */ public void plugIn(TargetHongkongPanelInterface targetHongkongPanel) { targetHongkongPanel.offerHongKongElectricity(); } /* * 測試主程序,港版插頭 插入到適配器上 * 適配器插入到大陸面板上 */ public static void main(String ...args) { //港版插頭 ClientHongKongSocket socket = new ClientHongKongSocket(); //大陸面板 AdapteeChinaMainlandPanel adapteeChinaMainlandPanel = new AdapteeChinaMainlandPanel(); //適配器 Adapter adapter = new Adapter(adapteeChinaMainlandPanel); //港版插頭 插到 適配器上 socket.plugIn(adapter); } }
package adapter; /**適配器角色 Adapter * 實現目標角色 TargetHongkongPanelInterface * 組合使用被適配角色 AdapteeChinaMainlandPanelInterface * 將對目標角色的方法調用轉換爲被適配角色的方法調用 * @author noteless * */ public class Adapter implements TargetHongkongPanelInterface{ private AdapteeChinaMainlandPanelInterface adapteeChinaMainlandPanel; Adapter(AdapteeChinaMainlandPanel adapteeChinaMainlandPanel){ this.adapteeChinaMainlandPanel = adapteeChinaMainlandPanel; } @Override public void offerHongKongElectricity() { adapteeChinaMainlandPanel.offerChinaMainlandElectricity(); } }
意圖:
將一個類的接口轉換成客戶但願的另一個接口。
適配器模式使得本來因爲接口不兼容而不能一塊兒工做的那些類能夠一塊兒工做.
注意:此處說的接口,並非單純的指Interface,而是指一切能夠提供方法調用的類型,多是接口也多是類
|
客戶使用適配器的過程:
客戶經過目標接口調用適配器的方法,對適配器發出請求
適配器使用被適配者接口把請求進行處理
客戶接收到調用的結果,可是並未察覺這一切是適配器在起轉換做用.
|
適配器三種模式 |
類適配器 對象適配器 接口適配器 |
想要把一個類的接口轉換爲客戶但願的另一個接口 必需要有輸入輸出,有目標 有源 因此做爲一個適配器,必需要 一手拿着被適配者也就是源 另外一手拿着的是目標 想要轉變爲目標,那麼必須得同目標時同樣的類型, 在oop中想要成爲目標類型 要麼繼承 要麼實現 想要擁有被適配者,要麼繼承,要麼實現,要麼就是關聯(擁有一個對象) 三種方式能夠理解爲按照 擁有被適配者 的方式進行劃分的 若是繼承Adaptee,那麼就是類 適配器 若是擁有一個Adaptee,也就是擁有一個Adaptee對象,那麼就是對象 適配器 若是實現Adaptee,那麼就是 接口適配器 |
類適配器
根據上面的描述,若是繼承Adaptee,那麼就是類 適配器,
在Java中不容許多繼承,既然已經繼承了Adaptee ,那麼就必需要求目標是一個接口(此處接口就是Interface)
這就有必定的侷限性
並且,既然是繼承被適配者類,那麼,被適配者的子類擁有的方法和行爲,他並不能擁有,也就是說不能適配被適配者的子類
|
優勢,那就是,適配器做爲被適配者的子類,天然擁有更多的操做空間,好比重寫方法 |
對象適配器 |
如同咱們上面的例子同樣,若是把被適配者當作一個屬性對象放到適配器中,這就是對象適配器
顯然,他不要求目標必定是接口, 繼承仍是實現均可以
同類適配器比較的話,顯然,他不能對被適配者 原來的一些方法進行操做,只能進行使用,不過也無傷大雅,不算缺點
由於他是擁有一個被適配者類型的對象,那麼,被適配者和他的子類顯然均可以做爲具體的對象傳入
|
接口適配器 按照咱們的描述,若是實現了被適配者 Adaptee 那麼就是接口適配器 具體說來: 當不須要所有實現接口提供的方法時 可先設計一個抽象類實現接口,併爲該接口中每一個方法提供一個默認實現(空方法) 那麼該抽象類的子類可有選擇地覆蓋父類的某些方法來實現需求 它適用於一個接口不想使用其全部的方法的狀況 |
package interfaceadapter; public interface Interfaces { public void method1(); public void method2(); public void method3(); public void method4(); public void method5(); }
package interfaceadapter; /** * @author noteless * */ public abstract class AbstractClass implements Interfaces { @Override public void method1() { } @Override public void method2() { } @Override public void method3() { } @Override public void method4() { } @Override public void method5() { } }
package interfaceadapter; public class ImplementClass1 extends AbstractClass { @Override public void method1() { System.out.println("method1 called "); } @Override public void method3() { System.out.println("method3 called "); } @Override public void method5() { System.out.println("method5 called "); } } package interfaceadapter; public class ImplementClass2 extends AbstractClass { @Override public void method2() { System.out.println("method2 called"); } @Override public void method4() { System.out.println("method4 called"); } }
package interfaceadapter; public class Test { public static void main(String[] args) { Interfaces class1 = new ImplementClass1(); Interfaces class2 = new ImplementClass2(); class1.method1(); class1.method2(); class1.method3(); class1.method4(); class1.method5(); System.out.println("------"); class2.method1(); class2.method2(); class2.method3(); class2.method4(); class2.method5(); } }
package doubleadapter; public interface TargetInterface { void targetRequest(); } package doubleadapter; public class TargetImplClass implements TargetInterface{ @Override public void targetRequest() { System.out.println("targetRequest ... "); } }
package doubleadapter; public interface AdapteeInterface { void adapteeRequest(); } package doubleadapter; public class AdapteeImplClass implements AdapteeInterface{ @Override public void adapteeRequest() { System.out.println("adapteeRequest ... "); } }
package doubleadapter; public class Adapter implements TargetInterface,AdapteeInterface { private TargetInterface target; private AdapteeInterface adaptee; Adapter(TargetInterface target){ this.target = target; } Adapter(AdapteeInterface adaptee){ this.adaptee = adaptee; } @Override public void adapteeRequest() { target.targetRequest(); } @Override public void targetRequest() { adaptee.adapteeRequest(); } }
適配器Adapter模式的宗旨是:
保留現有類所提供的服務,向客戶提供接口,以知足客戶的指望,也就是將現有接口轉換爲客戶但願的另外的一個接口
本質在於轉換
|
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package org.apache.commons.collections.iterators; import java.util.Collection; import java.util.Enumeration; import java.util.Iterator;
public class EnumerationIterator implements Iterator { private Collection collection; private Enumeration enumeration; private Object last; public EnumerationIterator() { this((Enumeration)null, (Collection)null); } public EnumerationIterator(Enumeration enumeration) { this(enumeration, (Collection)null); } public EnumerationIterator(Enumeration enumeration, Collection collection) { this.enumeration = enumeration; this.collection = collection; this.last = null; } public boolean hasNext() { return this.enumeration.hasMoreElements(); } public Object next() { this.last = this.enumeration.nextElement(); return this.last; } public void remove() { if (this.collection != null) { if (this.last != null) { this.collection.remove(this.last); } else { throw new IllegalStateException("next() must have been called for remove() to function"); } } else { throw new UnsupportedOperationException("No Collection associated with this Iterator"); } } public Enumeration getEnumeration() { return this.enumeration; } public void setEnumeration(Enumeration enumeration) { this.enumeration = enumeration; } }
public class EnumerationIterator implements Iterator {
private Enumeration enumeration;
|
設計模式是做爲解決問題或者設計類層級結構時的一種思惟的存在,而不是公式同樣的存在!
|