爲子系統中的一組接口提供一個一致的界面,外觀模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。
簡而言之就是,外觀模式可使客戶端不用關心各個子系統之間的交互邏輯,它只須要知道擔任「外觀角色」的接口是哪一個就足夠了。
某個週六臨近中午時,小明餓了!爲了填飽肚子,他只能從牀上爬起來,準備作飯。
要知道,這可不是件容易的事情!畢竟本身作飯的話,須要先去菜市場買菜,洗菜,而後才能作菜。起碼也得折騰一小時,才能吃上飯!
雖然很不情願,但別無選擇!c#
class BuyVegetables { /// <summary> /// 買菜 /// </summary> public static void Buy() { Console.WriteLine("買完食材了。"); } }
class Cleanout { /// <summary> /// 洗菜 /// </summary> public static void Clean() { Console.WriteLine("該洗的菜都洗好了。"); } }
class Cooking { /// <summary> /// 作菜 /// </summary> public static void Cook() { Console.WriteLine("飯菜作好了。"); } }
該忙的都忙完了,能夠開飯了!設計模式
class Program { static void Main(string[] args) { Console.WriteLine("該吃飯了···"); BuyVegetables.Buy(); Cleanout.Clean(); Cooking.Cook(); Console.WriteLine("吃飽喝足。"); } }
這頓飯還真是把小明折騰慘了!!!spa
一週過去了···.net
又到了週六,又到了臨近中午的時間點,小明又餓了···
多麼似曾相識的一幕~~~
但今天他實在不想再作飯了,因此,他選擇了訂外賣!!!設計
不過,想訂外賣,首先得有餐館的聯繫方式。
這個訂餐服務
其實就充當了外觀者的邏輯入口。code
class Restaurant { /// <summary> /// 外賣服務 /// </summary> public static void Order() { Console.WriteLine("已收到訂單,正在出餐···"); BuyVegetables.Buy(); Cleanout.Clean(); Cooking.Cook(); Console.WriteLine("已出餐,正在配送中···"); } }
有了餐館的聯繫方式後,就簡單了。中間件
class Program { static void Main(string[] args) { Console.WriteLine("該吃飯了,點個外賣吧···"); Restaurant.Order(); Console.WriteLine("收到外賣,開飯!"); Console.WriteLine("吃飽喝足,順便還打了個飽嗝···"); } }
此次可輕鬆了。blog
場景1中,客戶(小明)與吃飯這件事的交互至關麻煩,整個流程他本身作下來要費很多心思!實際工做中,這種場景很是常見,每一次都把子系統的邏輯耦合到客戶端內,那麼客戶端將變得至關臃腫,且不穩定。
此時,提供一箇中間件(外觀者),也就是場景2中的「餐館」,這樣的話,小明只要一個電話,買菜,洗菜,作菜這種事情就都有人幫他解決了。實際工做中,也能夠提供一個外觀者,由它來負責和各個子系統(或者子功能)的交互。這個外觀者對客戶端提供一個入口方法,而客戶端只須要調用這個入口方法,就能夠把全部想作的事情所有處理掉,這樣勢必會減輕客戶端的複雜度。接口
若是某一天,小明只是隨便點了一份清湯麪,這樣的話餐館就不用洗菜,只須要買麪條,而且煮好送到小明的手裏就行了。那怎麼辦呢?難道要改外觀者的代碼,把裏面的Cleanout.Clean();
代碼刪掉?這豈不是違反了開閉原則?
是的,若是這樣處理,那麼勢必會違反開閉原則!get
怎麼辦呢?此時能夠把外觀者角色抽象出來!
interface IRestaurant { /// <summary> /// 訂餐服務 /// </summary> void Order(); }
而後實現一個具體外觀者-麪館。
class NoodleRestaurant : IRestaurant { public void Order() { Console.WriteLine("已收到訂單,正在出餐···"); BuyVegetables.Buy(); Cooking.Cook(); Console.WriteLine("已出餐,正在配送中···"); } }
這樣小明只須要在想吃麪的時候,使用new NoodleRestaurant().Order()
便可成功訂餐!
以上。