這幾個模式比較相似, 都是用做interface, 但有所不一樣
Proxy, 特色是以假亂真, client在使用的時候就和在使用真正的object同樣, 接口徹底一致, proxy和object的交互是對client透明的
Adapter, 典型的是電源的adapter, 美標換歐標, 即解決接口不匹配, client和lib都已經寫好, 但接口不匹配
Facade, 用於屏蔽子系統的細節, 提供高層接口層
Mediator, 典型的房產中介, 當對象之間關係複雜的時候, 避免對象之間的直接溝通web
其中Adapter和Facade是在不得已的狀況下采用的, 即已有legacy的系統, 很難改變的狀況下的折衷方案網絡
代理(Proxy)模式給某一個對象提供一個代理,並由代理對象控制對原對象的引用。
場景, 在軟件系統中,有些對象有時候因爲跨越網絡或者其餘的障礙,而不可以或者不想直接訪問另外一個對象.
這個模式很容易理解, 並且實際應用不少, 如
遠程(Remote)代理, 典型的例子, webservice遠程調用, RPC
保護(Protect or Access)代理, 控制訪問權限
虛擬(Virtual)代理, 當建立消耗資源很大的對象時使用, 如打開不少圖片的Html, 會先顯示文字, 而圖片會下載結束後才顯示, 那些未打開的圖片框就是用虛擬代理來替代真實圖片.
智能引用(Smart Reference)代理:代理須要處理一些額外的事, 如引用計數, 計數爲0時釋放引用等.
可見這個模式雖然簡單, 可是仍是頗有用的, 代理提供了一層封裝, 使客戶在訪問到真正對象前, 能夠作預先的處理, 靈活性很大.ide
以下圖, Subject類定義了RealSubject和Proxy公共的接口, 這樣在任何使用RealSubject的地方均可以使用Proxy
this
class RealSubject : Subject { void Request() { print("Real request");} } class Proxy : Subject { RealSubject realSub; //真實對象 void request() { realSub.Request(); } //能夠在訪問真實對象時, 添加任何邏輯 }
用戶使用直接訪問代理
spa
Proxy p = new Proxy()
p.Request()
門面模式 (facade)又稱外觀模式, 爲子系統中的一組接口提供一個一致的界面, Facade 模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。
這個模式很簡單, 當子系統接口比較複雜時, 若是讓客戶直接使用子系統接口, 有以下問題,
系統難於使用, 客戶須要先熟悉複雜的子系統接口
耦合度太高, 當子系統改變時, 會影響到客戶類
這樣明顯違反了迪米特法則和依賴倒轉法則, 因此咱們的作法就是提供一個相對簡單的高層抽象接口來屏蔽底層子系統的細節,從而解決了上面兩個問題.
這個模式很簡單, 也很經常使用, 不管你是否知道這個模式設計
適配器模式 (Adapter), 將一個類的接口轉換成客戶但願的另一個接口。Adapter模式使得本來因爲接口不兼容而不能一塊兒工做的那些類能夠一塊兒工做。
這個模式很簡單, 通常用於對已有系統的porting和重用. 這個模式應該是不得已而爲之, 由於直接改變原來系統的接口確定不合適, 因此爲了能夠重用這個系統必須增長一層adapter.3d
中介者模式(Mediator), 用一箇中介對象來封裝一系列的對象交互. 中介者使各對象不須要顯式地相互引用, 從而使其耦合鬆散, 並且能夠獨立地改變它們之間的交互.代理
這個模式很好理解, 如房產中介, 留學中介, 固然最大的中介者,聯合國. 中介的目的就是解耦合, 使得能夠獨立地改變和複用各個同事對象和中介者類. 對象
對於面向對象設計, 須要將系統分割成許多對象以增長複用性, 可是對象間激增的相互關聯有大大下降了其複用性, 大量的關聯致使對象間緊耦合, 修改一個對象就會致使全部和該對象相關聯的對象的改動, 牽一髮而動全身.
可是面對這種狀況, 首先想到的不該該是用中介者模式, 而是系統設計不合理, 設計時應儘可能的高聚合低耦合, 而對象間大量的關聯致使高耦合, 頗有多是設計不合理, 系統分割過細緻使的, 通常經過從新設計就能夠解決.
中介者模式適用於, 對象間關係確實很複雜, 如聯合國, 各國間關係錯綜複雜, 因而須要一箇中介者把對象間複雜的交換剝離出來交給中介者來處理.
這個模式的缺點就是, 因爲把全部對象間交換集中在中介者, 會致使中介者邏輯會過於複雜.blog
class ConcreteMediator : Mediator { //中介者須要認識全部的同事對象 private ConcreteColleague1 colleague1; private ConcreteColleague2 colleague2; public override void Send(string message,Colleague colleague) { //根據各類條件在不一樣的同事對象間經行交互 //這段邏輯每每會變的很複雜 if (colleague == colleague1) { colleague2.Notify(message); } else { colleague1.Notify(message); } } } class ConcreteColleague1 : Colleague { protected Mediator mediator; //同事對象只須要認識中介者, 而不須要認識其餘任何同事 // Constructor public ConcreteColleague1(Mediator mediator) : base(mediator) { } public void Send(string message) { mediator.Send(message, this); //須要和其餘同事交互時, 經過中介者 } public void Notify(string message) //提供給中介者的交互接口 { Console.WriteLine("Colleague1 gets message: "+ message); } } //客戶代碼 ConcreteMediator m = new ConcreteMediator(); ConcreteColleague1 c1 = new ConcreteColleague1(m); ConcreteColleague2 c2 = new ConcreteColleague2(m); m.Colleague1 = c1; m.Colleague2 = c2; c1.Send("How are you?"); c2.Send("Fine, thanks");