外观模式(或门面模式、包装模式)是设计模式中非常朴素地体现面向对象“封装”概念的模式,它的基本原理是将复杂的内部实现以统一接口的方式暴露出来,最大程度地减少客户程序对某些子系统内部众多对象的依赖关系。
外观模式在开发过程中运用频率非常高,比如各种第三方SDK大多会使用外观模式。通过一个外观类是的整个系统的接口只有一个统一的高层接口,这样能够降低用户的使用成本,也能够对用户屏蔽很多实现细节。 再比如经常会用到的三层结构也是外观模式的应用。
GOF对外观模式的描述为: Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use. — Design Patterns : Elements of Reusable Object-Oriented Software
UML类图:
通过外观模式为子系统中的一组接口提供一个高层接口,该接口使子系统更易于使用。它的主要动机是减少“子系统”内部与外部间对象通信的依赖复杂程度
再比如计算机就是一个通过提供一个高层接口以屏蔽内部复杂性的例子,计算机包括CPU、硬盘、内存等各种部件,但作为用户,不需要与这些零部件打交道,只需要按一下开机键,电脑就会启动,只要点击操作系统的关机按钮,电脑就会关机。
计算机例子的代码实现:
public class SubSystemBase
{
private string SubsystemName { get; set; }
public SubSystemBase(string subsystemName)
{
this.SubsystemName = subsystemName;
}
public void Startup()
{
Console.WriteLine($"{this.SubsystemName} startup");
}
public void Shutdown()
{
Console.WriteLine($"{this.SubsystemName} shutdown");
}
}
public class CPU : SubSystemBase
{
public CPU() : base("CPU") { }
}
public class Disk : SubSystemBase
{
public Disk() : base("Disk") { }
}
public class Memory : SubSystemBase
{
public Memory() : base("Memory") { }
}
//外观模式提供的统一接口
public class ComputerFacade
{
CPU cpu = new CPU();
Disk disk = new Disk();
Memory memory = new Memory();
public void Startup()
{
cpu.Startup();
disk.Startup();
memory.Startup();
}
public void Shutdown()
{
cpu.Shutdown();
disk.Shutdown();
memory.Shutdown();
}
}
外观模式的适用场景
- 为复杂的模块或子系统提供外界访问的模块。
- 子系统相对独立。
- 方便建立统一的开发规范。
外观模式的优点
- 减少系统相互依赖。
- 提高灵活性。
- 提高了安全性、规范性。
外观模式的缺点 外观虽然有很多优点,但也不可避免地会有其固有的缺点,最主要的就是不符合开闭原则,如果要修改东西会很麻烦,关联修改很多内容,这一点在三层架构就深有体会。
参考书籍: 王翔著 《设计模式——基于C#的工程化实现及扩展》