为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
简而言之就是,外观模式可使客户端不用关心各个子系统之间的交互逻辑,它只须要知道担任“外观角色”的接口是哪一个就足够了。
某个周六临近中午时,小明饿了!为了填饱肚子,他只能从床上爬起来,准备作饭。
要知道,这可不是件容易的事情!毕竟本身作饭的话,须要先去菜市场买菜,洗菜,而后才能作菜。起码也得折腾一小时,才能吃上饭!
虽然很不情愿,但别无选择!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()
便可成功订餐!
以上。