前言
外观模式,又称门面模式,对象结构型模式。在《设计模式 - 可复用的面向对象软件》一书中将之描述为“ 为系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用 ”。
模式
需要角色如下:
- Facade(门面):子系统为外部提供的入库,负责将外部的调用委派给子系统实现;
- Subsystem(子系统);与Facade相互独立,负责功能的实现;
场景
在日常生活中,我们经常接触到与外观模式相识的场景。比如操作系统就是电脑提供给我们的Facade,用来控制电脑执行相应的操作。苹果手机通过App Store下载APP,App Store就是提供给我们的Facade。如果没有这些,我们在使用电脑时就需要使用汇编来操作电脑,在下载APP时就需要分别去每个APP的官网下载。由于Facade的存在使得我们更加方便的与其它事物交互。
示例
public class AppA { public void Download() { Console.WriteLine("寻找appA的下载地址"); Console.WriteLine("访问appA的下载地址"); Console.WriteLine("开始下载"); Console.WriteLine("appA下载完毕"); } public void Install() { Console.WriteLine("寻找appA的安装文件"); Console.WriteLine("开始安装"); Console.WriteLine("appA安装完毕"); } } public class AppB { public void Download() { Console.WriteLine("寻找appB的下载地址"); Console.WriteLine("访问appB的下载地址"); Console.WriteLine("开始下载"); Console.WriteLine("appB下载完毕"); } public void Install() { Console.WriteLine("寻找appB的安装文件"); Console.WriteLine("开始安装"); Console.WriteLine("appB安装完毕"); } } public class AppStoreFacade { private AppA _appA = null; private AppA appA { get { if(this._appA == null) { this._appA = new AppA() } return this._appA; } } private AppB _appB = null; private AppB appB { get { if(this._appB == null) { this._appB = new AppB() } return this._appB; } } public void DownloadAppA() { this.appA.Download(); Console.WriteLine("---------"); this.appA.Install(); } public void DownloadAppB() { this.appB.Download(); Console.WriteLine("---------"); this.appB.Install(); } } static void Main(string[] args) { AppStoreFacade facade = new AppStoreFacade(); facade.DownloadAppA(); Console.ReadKey(); }
如上所示,在Facade模式下,我们暴露给用户的只有一个AppStoreFacade类,用户只能通过该类使用该系统的某些功能时(比如下载APP),利用这个类使该系统对用户透明。
在所有的设计模式中一直强调的就是“ 针对接口编程,而不是针对实现编程 ”。接口能够保证所有实现类的一致性,方便我们对其进行扩展。所以我们可以将AppStoreFacade抽象出一个接口,并通过一个抽象工厂 (Abstract Factory) 来获取Facade实例。这样做的好处是在需求发生变更时只需要增加新的Facade类以及对应的抽象工厂实例即可。并且在同时存在多个系统需要对外提供Facade时(比如在Android中同时存在多个应用市场类软件)能够使这几个系统对用户更加透明。
总结
外观模式,就是把一个系统对外提供的操作进行封装让用户更加方便的使用,并且将用户与系统进行解耦,使系统的内部模块更容易扩展与维护。但用户方便使用的同时也牺牲了该系统对于用户的灵活性。
以上,就是我对外观模式的理解,希望对你有所帮助。
示例源码:https://gitee.com/wxingChen/DesignPatternsPractice
系列汇总:https://www.cnblogs.com/wxingchen/p/10031592.html
本文著作权归本人所有,如需转载请标明本文链接(https://www.cnblogs.com/wxingchen/p/10078618.html)