定义:
外观模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。外观模式又称为门面模式,它是一种对象结构型模式。
外观模式参与者
- Facade:外观类,知道哪些子系统类负责处理请求,将客户的请求代理给适当的子系统对象。
- Subsystem:子系统。
外观模式基本代码
Facade类:
namespace FacadePattern.BasicStructure { /// <summary> /// 外观类 /// </summary> class Facade { private SubSystemOne _subSystemOne; private SubSystemTwo _subSystemTwo; private SubSystemThree _subSystemThree; private SubSystemFour _subSystemFour; public Facade() { _subSystemOne = new SubSystemOne(); _subSystemTwo = new SubSystemTwo(); _subSystemThree = new SubSystemThree(); _subSystemFour = new SubSystemFour(); } public void MethodA() { Console.WriteLine(" 方法组A() ---"); _subSystemOne.Method(); _subSystemTwo.Method(); _subSystemFour.Method(); } public void MethodB() { Console.WriteLine(" 方法组B() ---"); _subSystemTwo.Method(); _subSystemThree.Method(); } } }
SubSystemOne类:
namespace FacadePattern.BasicStructure { /// <summary> /// 子系统一 /// </summary> class SubSystemOne { public void Method() { Console.WriteLine("子系统一的方法"); } } }
SubSystemTwo类:
namespace FacadePattern.BasicStructure { /// <summary> /// 子系统二 /// </summary> class SubSystemTwo { public void Method() { Console.WriteLine("子系统二的方法"); } } }
SubSystemThree类:
namespace FacadePattern.BasicStructure { /// <summary> /// 子系统三 /// </summary> class SubSystemThree { public void Method() { Console.WriteLine("子系统三的方法"); } } }
SubSystemFour类:
namespace FacadePattern.BasicStructure { /// <summary> /// 子系统四 /// </summary> class SubSystemFour { public void Method() { Console.WriteLine("子系统四的方法"); } } }
客户端调用代码:
static void Main(string[] args) { try { {//BasicStructure //由于Facade的作用,客户端根本不知道子4个子系统的存在 Facade facade = new Facade(); facade.MethodA(); facade.MethodB(); } } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.ReadKey(); }
结果如下:
用外观模式实现笔记本电脑开机关机
场景模拟:本人每天都要给笔记本电脑开机关机,接下来就用外观模式来模拟下。
NotebookPowerSupply(笔记本电源)类——Facade类
namespace FacadePattern.SituationSimulation { /// <summary> /// 笔记本电脑电源键--相当于外观类 /// </summary> class NotebookPowerSupply { private OpenPowerSupply _openPowerSupply; private ClosePowerSupply _closePowerSupply; public NotebookPowerSupply() { _openPowerSupply = new OpenPowerSupply(); _closePowerSupply = new ClosePowerSupply(); } public void Open() { Console.WriteLine(" --开启电源方法"); _openPowerSupply.Operation(); } public void Close() { Console.WriteLine(" --关闭电源方法"); _closePowerSupply.Operation(); } } }
OpenPowerSupply(开启电源)类——SubSystem类
namespace FacadePattern.SituationSimulation { /// <summary> /// 打开电源 /// </summary> class OpenPowerSupply { public void Operation() { Console.WriteLine("打开电源"); } } }
ClosePowerSupply(关闭电源)类——SubSystem类
namespace FacadePattern.SituationSimulation { /// <summary> /// 关闭电源 /// </summary> class ClosePowerSupply { public void Operation() { Console.WriteLine("关闭电源"); } } }
客户端调用代码:
static void Main(string[] args) { try { {//SituationSimulation NotebookPowerSupply notebookPowerSupply = new NotebookPowerSupply(); notebookPowerSupply.Open(); notebookPowerSupply.Close(); } } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.ReadKey(); }
结果如下:
优点:
外观模式的优点
- 对客户屏蔽子系统组件,减少了客户处理的对象数目并使得子系统使用起来更加容易。通过引入外观模式,客户代码将变得很简单,与之关联的对象也很少。
- 实现了子系统与客户之间的松耦合关系,这使得子系统的组件变化不会影响到调用它的客户类,只需要调整外观类即可。
- 降低了大型软件系统中的编译依赖性,并简化了系统在不同平台之间的移植过程,因为编译一个子系统一般不需要编译所有其他的子系统。一个子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到外观对象。
- 只是提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类。
缺点:
外观模式的缺点
- 不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少了可变性和灵活性。
- 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。
适用环境:
在以下情况下可以使用外观模式:
- 当要为一个复杂子系统提供一个简单接口时可以使用外观模式。该接口可以满足大多数用户的需求,而且用户也可以越过外观类直接访问子系统。
- 客户程序与多个子系统之间存在很大的依赖性。引入外观类将子系统与客户以及其他子系统解耦,可以提高子系统的独立性和可移植性。
- 在层次化结构中,可以使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度。
总结:
- 在外观模式中,外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。外观模式又称为门面模式,它是一种对象结构型模式。
- 外观模式包含两个角色:外观角色是在客户端直接调用的角色,在外观角色中可以知道相关的(一个或者多个)子系统的功能和责任,它将所有从客户端发来的请求委派到相应的子系统去,传递给相应的子系统对象处理;在软件系统中可以同时有一个或者多个子系统角色,每一个子系统可以不是一个单独的类,而是一个类的集合,它实现子系统的功能。
- 外观模式要求一个子系统的外部与其内部的通信通过一个统一的外观对象进行,外观类将客户端与子系统的内部复杂性分隔开,使得客户端只需要与外观对象打交道,而不需要与子系统内部的很多对象打交道。
- 外观模式主要优点在于对客户屏蔽子系统组件,减少了客户处理的对象数目并使得子系统使用起来更加容易,它实现了子系统与客户之间的松耦合关系,并降低了大型软件系统中的编译依赖性,简化了系统在不同平台之间的移植过程;其缺点在于不能很好地限制客户使用子系统类,而且在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。
- 外观模式适用情况包括:要为一个复杂子系统提供一个简单接口;客户程序与多个子系统之间存在很大的依赖性;在层次化结构中,需要定义系统中每一层的入口,使得层与层之间不直接产生联系。