1.適配器(Adapter)模式部分
*OO適配器和真實世界的適配器扮演者同樣的角色:將一個接口轉(zhuǎn)換成另一個接口,以符合客戶的期望。
*適配器(Adapter)類看起來很像命令(Command)模式中命令接口的實現(xiàn)類,只不過它不被作為參數(shù)傳遞。
- ----DuckAdapter類----
- public class DuckAdapter implements Turkey {
- private Duck duck;
-
- public DuckAdapter(Duck duck) {
- this.duck = duck;
- }
-
- public void goggle() {
- duck.quack();
- }
-
- public void fly() {
- duck.fly();
- }
- }
- ------------
----DuckAdapter類----public class DuckAdapter implements Turkey {private Duck duck;public DuckAdapter(Duck duck) {this.duck = duck;}public void goggle() {duck.quack();}public void fly() {duck.fly();}}------------
適配器模式:將一個類的接口,轉(zhuǎn)換成客戶希望的另一個接口。適配器讓原本接口不兼容的類合作無間。
*適配器模式可以讓客戶從實現(xiàn)的接口解耦。
*適配器(Adapter)模式充滿著良好的OO設(shè)計原則:使用對象組合,以修改的接口包裝被適配者;這種做法還有額外的優(yōu)點,那就是被適配者的任何子類都可以搭配著適配器使用。
*適配器(Adapter)分為“對象(Object)”適配器和“類(Class)”適配器兩種。
*在類適配器中,適配器繼承了目標(Target)和被適配者(Adaptee);而對象適配器中,適配器利用組合的方式將請求傳送給被適配者。
*類適配器是基于多重繼承實現(xiàn)的,因為Java不支持多重繼承,因此無法做到。
*由于類適配器使用了繼承的方式,所以它的優(yōu)點是不需要整個實現(xiàn)被適配者,必要的時候還可以覆蓋被適配者的行為。
- ----練習(xí)。解答----
- public class ArrayListEnumeration implements Enumeration {
- private ArrayList list;
-
- public ArrayListEnumeration(ArrayList al) {
- this.list = al;
- }
-
- public boolean hasMoreElements() {
- return list.iterator().hasNext();
- }
-
- public Object nextElement() {
- return list.iterator().next();
- }
- }
- ------------
----練習(xí)。解答----public class ArrayListEnumeration implements Enumeration {private ArrayList list;public ArrayListEnumeration(ArrayList al) {this.list = al;}public boolean hasMoreElements() {return list.iterator().hasNext();}public Object nextElement() {return list.iterator().next();}}------------
引用
*裝飾者(Decorator)模式與適配器(Adapter)模式的區(qū)別
(1)裝飾者模式與“責(zé)任”相關(guān),當(dāng)涉及到裝飾者時,就表示有一些新的行為或責(zé)任要加到設(shè)計中。
(2)適配器允許客戶使用新的庫和子集合,無須改變“任何”已存在的代碼,由適配器負責(zé)轉(zhuǎn)換即可。
(3)裝飾者不會改變接口,而適配器會改變接口。
(4)裝飾者的工作是擴展被包裝對象的行為或責(zé)任,并不是“簡單傳遞”就算了。
(5)裝飾者(Decorator)模式與適配器(Adapter)模式的最大不同在于使用它們的意圖(或目的)。
----連連看解答----
裝飾者(Decorator)模式->不改變接口,但加入責(zé)任
適配器(Adapter)模式->將一個接口轉(zhuǎn)換成另一個接口
外觀(Facade)模式->讓接口更簡單
------------
2.外觀(Facade)模式部分
*外觀模式在簡化接口的同時,依然將系統(tǒng)完整的功能暴露出來,一共需要的人使用。
*外觀模式不僅簡化了接口,也將客戶從組件的子系統(tǒng)中解耦。
*適配器(Adapter)模式和外觀(Facade)模式都可以包裝多個類,前者的目的是將接口重新組織后提供新接口,后者的目的是簡化接口。由于它們的差異很細微,所以兩者常常同時出現(xiàn)。
外觀模式:提供了一個統(tǒng)一的接口,用來訪問子系統(tǒng)中的一群接口。外觀模式定義了一個高層接口,讓子系統(tǒng)更容易使用。
軟件設(shè)計原則:要減少對象之間的交互,只留下幾個“密友”。這個原則被成為“最少知識(Least Knowledge)原則”,它告訴我們只和自己的密友談話。
*最少知識(Least Knowledge)原則告訴我們,不要讓太多的類耦合在一起,免得修改系統(tǒng)的一部分,會影響到其它部分。如果許多類之間互相依賴,那么這個系統(tǒng)就是一個易碎的系統(tǒng),需要花許多成本維護,也會因為太復(fù)雜而不容易被他人理解。
引用
*通過只調(diào)用以下幾種范圍內(nèi)的方法可以做到盡量遵循“最少知識原則”:
(1)該對象本身
(2)被當(dāng)做方法的參數(shù)而傳遞進來的對象
(3)此方法所創(chuàng)建或?qū)嵗娜魏螌ο?
(4)對象的任何組件,比如類或?qū)ο蟊旧淼淖兞?,或常?/div>
*最少知識原則的不同名稱:(Principal of) Least Knowledge,(The) Law of Demeter,迪米特法則,得墨忒耳法則
*使用最少知識原則的缺點是:更多的“包裝類”被創(chuàng)造出來,以處理和其它組件的溝通。這可能導(dǎo)致復(fù)雜度和開發(fā)時間的增加,并減低運行時的性能。
引用
----Sharpen Your Pencil----
第一個House類違反了“最少知識原則”,第二個House類則沒有。
------------
3.適配器(Adapter)模式和外觀(Facade)模式小結(jié)
*當(dāng)需要使用一個現(xiàn)有的類,而其接口并不符合你的需要時,就使用適配器。
*當(dāng)需要簡化并統(tǒng)一一個很大的接口或者一群復(fù)雜的接口時,使用外觀。
*適配器改變接口以符合客戶的期望。
*外觀將客戶從一個復(fù)雜的子系統(tǒng)中解耦。
*實現(xiàn)一個適配器所要花費的工作量取決于目標接口的大小及復(fù)雜程度。
*實現(xiàn)一個外觀,需要將子系統(tǒng)組合進外觀中,然后將工作委托給子系統(tǒng)執(zhí)行。
*適配器有兩種形式:對象適配器和類適配器。類適配器需要用到多重繼承。
*可以為一個子系統(tǒng)實現(xiàn)一個以上的外觀。
*適配器(Adapter)將一個對象包裝起來以改變其接口;裝飾者(Decorator)將一個對象包裝起來以增加新的行為和責(zé)任;而外觀(Facade)將一群對象包裝起來以簡化其接口。
4.適配器(Adapter)模式實例
-
- public class ListEnumeration implements Enumeration {
- private List list;
-
- public ListEnumeration(List al) {
- this.list = al;
- }
-
- public boolean hasMoreElements() {
- return list.iterator().hasNext();
- }
-
- public Object nextElement() {
- return list.iterator().next();
- }
- }
// 讓所有List支持枚舉public class ListEnumeration implements Enumeration {private List list;public ListEnumeration(List al) {this.list = al;}public boolean hasMoreElements() {return list.iterator().hasNext();}public Object nextElement() {return list.iterator().next();}}
5.外觀(Facade)模式實例
-
- public class CarLock {
- public void lock() {
- System.out.println("Car is locked.");
- }
-
- public void unlock() {
- System.out.println("Car is unlock.");
- }
- }
-
-
- public class Engine {
- public void start() {
- System.out.println("Engine is started.");
- }
-
- public void stop() {
- System.out.println("Engine is stopped.");
- }
- }
-
-
- public class CarFacade {
- private CarLock lock;
-
- private Engine engine;
-
- public CarFacade(CarLock lock, Engine engine) {
- this.lock = lock;
- this.engine = engine;
- }
-
- public void startCar() {
- this.lock.unlock();
- this.engine.start();
- }
-
- public void stopCar() {
- this.engine.stop();
- this.lock.lock();
- }
- }
// 車鎖public class CarLock {public void lock() {System.out.println("Car is locked.");}public void unlock() {System.out.println("Car is unlock.");}}// 發(fā)動機public class Engine {public void start() {System.out.println("Engine is started.");}public void stop() {System.out.println("Engine is stopped.");}}// 汽車外觀類public class CarFacade {private CarLock lock;private Engine engine;public CarFacade(CarLock lock, Engine engine) {this.lock = lock;this.engine = engine;}public void startCar() {this.lock.unlock();this.engine.start();}public void stopCar() {this.engine.stop();this.lock.lock();}}
--END--