hello,你們好,今天是2月17號,星期一。這周仍是在家辦公,不得不說,在家工做沒啥熱情和壓力,是人類的天性嗎,不愛工做?html
好了,咱話也很少說啥了,畢竟以後的生活仍是很嚴峻。設計模式
若是咱要出國旅遊,其餘國家插座有采用歐標(兩孔圓),而國內的插頭都是兩孔扁的,即沒法使用,那不是涼涼了。在平常生活中,這個問題很好解決,咱們只要帶上多功能轉化插頭就ok啦,其相似於適配器。socket
這個例子是生活中的,那替換到代碼是什麼樣呢?好比咱們有一個類A,其有一個方法m1,也有一個類B,其也有一個方法m2,可是這兩個類的參數徹底不同。我若是想要在m1方法中使用m2方法怎麼辦呢?其實方法能夠相似,咱們也弄一個轉接插頭,新建一個Adapter,在其裏面完成二者的調用。ide
將某個類的接口轉化成客戶端指望的另外一個接口,主要目的是兼容性,讓本來因接口不匹配不能工做的兩個類能夠協同工做。this
須要注意的是,在設計之初儘可能不要考慮這種設計模式,會使得原本很簡單的代碼或邏輯變得複雜冗餘。咱們通常在項目後期,動代碼須要考慮的事情太多,容易出錯的時候,能夠考慮這種設計模式,使得代碼改起來比較方便且不易犯錯。spa
適配器主要有三種呈現形式,分別是:設計
類適配器(經過繼承插座類,實現插頭接口,完成插座到插頭的轉化)code
對象適配器(持有插座類,實現插頭接口,完成插座到插頭的轉化)htm
接口適配器對象
繼承插座類,實現插頭接口,完成插座到插頭的轉化。
有了uml圖,代碼就很簡單了,來溜溜代碼吧。
插頭接口:
public interface IPlug { public int output5V(); }
插座接口:
public class Socket { public int output220V(){ System.out.println("電源電壓220V"); return 220; } }
多功能轉接頭(適配器):
`public class Adapter extends Socket implements IPlug {
@Override
public int output5V() {
System.out.println("進入適配器,即多功能轉接頭");
int output220V=output220V();
int output5V=output220V/44;
return output5V;
}
}`
調用方:
public class Phone { public void work(IPlug iPlug){ System.out.println("當前電壓:"+iPlug.output5V()); } }
public class Client { public static void main(String[] args){ Phone phone=new Phone(); phone.work(new Adapter()); } }
調用結果:
因爲轉接頭類Adapter繼承了插座類Socket,在以前的設計模式七大原則中「里氏替換原則」就說明了少用繼承,繼承使得代碼耦合性增強,之後不利於改代碼。因此咱們針對上面的缺點,提出了對象適配器。
針對類適配器中的繼承關係作了一些調整,根據「合成複用原則」,在系統中儘可能使用關聯關係來替代繼承關係,即便用插座對象,將繼承關係轉化爲has關係,實現插頭接口,完成插座到插頭的轉化。
因爲這個和類適配器相似,只有Adapter代碼不同,因此其餘類就不寫了。
public class Adapter implements IPlug { private Socket socket ; public Adapter(Socket socket){ this.socket=socket; } @Override public int output5V() { System.out.println("進入適配器,即多功能轉接頭"); int output220V = socket.output220V(); int output5V = output220V / 44; return output5V; } }
public class Client { public static void main(String[] args){ Phone phone=new Phone(); phone.work(new Adapter(new Socket())); } }
對象適配器和類適配器其實算是同一種思想,只不過實現方式不一樣。
根據合成複用的原則,使用組合替代繼承,使用成本更低,更加靈活。
當不須要所有實現接口提供的方法時,先設計一個實現某接口的類,併爲該接口中的每一個方法提供一個默認實現,當子類不想使用全部方法的狀況下,就能夠選擇性的覆蓋父類方法完成需求。
`public interface ceshi {
public void m1();
public void m2();
public void m3();
public void m4();
}`
public abstract class Adapter implements ceshi { @Override public void m1() { } @Override public void m2() { } @Override public void m3() { } @Override public void m4() { } }
public class Client { public static void main(String[] args) { Adapter adapter = new Adapter() { public void m1() { //只須要覆蓋咱們使用的接口方法 System.out.println("m1"); } }; adapter.m1(); } }
運行結果:
1.沒有不符合系統的需求,經過適配器解決不兼容的問題,使得這些功能類獲得複用。
2.在必定程度上的解耦。
過多的使用適配器,增長系統的理解難度。
本文主要介紹了三種適配器模式,本質上是現有的不兼容的接口轉換爲須要的接口,既不須要改變原來的代碼結構便可實現新的功能。
類適配器模式,以繼承現有類的方式轉換。
對象適配器模式,以聚合對象實例的方式轉換。
接口適配器模式,以實現接口的方式轉換。
適配器模式是在現有的類和系統都不易修改的狀況下使用,在系統設計之初慎用適配器模式,這樣會致使代碼可讀性變差,不易維護。