【23种设计模式】之外观模式(Facade Pattern) .Net Core实现
外观模式(facade pattern),又称门面模式,是一种结构型模式,能为程序库、框架、复杂系统提供一个高层面的接口,以供客户端或使用者访问。
优点:减少了系统间的相互依赖,提高了系统灵活性,提供了系统安全性。
缺点:不符合开闭原则。
业务场景:系统内部复杂,客户端无需知道系统的复杂,更不能向客户端开放复杂的接口,向客户端开放简单而统一的一个接口即可。
关键代码:在客户端与系统之间增加一个独立的类。该类与客户端解耦。该类与系统耦合,将调用顺序、依赖关系处理好。
家庭影院需求
这个家庭影院有DVD播放器, 投影仪, 屏幕, 环绕立体音响, 还有个爆米花机:

你可能花了几周的时间去连线, 组装…现在你想看一个电影, 步骤如下:
- 打开爆米花机
- 开始制作爆米花
- 把灯光调暗
- 把屏幕放下来
- 把投影仪打开
- 把投影仪的输入媒介设为DVD
- 把投影仪调整为宽屏模式
- 打开功放
- 把功放的输入媒介设为DVD
- 把功放设置为环绕立体声
- 把功放的音量调到中档
- 把DVD播放器打开
- 开始播放DVD
具体用程序描述就是这样的:

但是还没完,当电影播放完了, 得把所有的设备关掉, 那么反向重新操作一遍?要是听CD或者收音机是不是也同样的麻烦?如果系统升级, 那么你还得学习一遍新的流程吧?
这个需求, 就需要使用外观模式了:
使用外观模式, 你可以通过实现一个外观类把一个复杂的子系统简单化, 因为这个外观类会提供一个更合理的接口.

HomeTheaterFacade这个外观类只暴露了几个简单的方法, 例如看电影watchMovie(). 这个外观类把整个家庭影院看作是它的子系统, 通过调用子系统的相关方法来实现对外的简单方法.
而客户只需要调用这些简单的方法即可. 但是外观类的子系统仍然保留着对外界的可直接访问性, 如果你需要高级功能, 就可以直接调用.
以下几点需要理解:
- 外观类并没有"封装"子系统, 它只不过是对子系统的功能额外提供了一套简单的方法. 外界仍然可以直接访问子系统的方法.
- 外观类也可以添加额外的功能.
- 针对一个子系统可以创建若干个外观类
- 外观模式让客户和子系统解耦.
- 适配器模式是把一个或多个类的接口转化成客户所需要的一个接口, 而外观模式则是提供了一个简单的接口. 它们之间的根本不同是它们的目的,
适配器是要改变接口, 以便可以符合客户要求; 外观模式则是为子系统提供一个简化的接口.
代码
这里只贴HomeTheaterFacade的代码吧, 其他的东西太简单了 (其他代码在这里: https://github.com/solenovex/Head-First-Design-Patterns-in-CSharp):
using System;
using FacadePattern.Equipments;
namespace FacadePattern.Facades
{
public class HomeTheaterFacade
{
private readonly Amplifier _amp;
private readonly DvdPlayer _dvd;
private readonly Projector _projector;
private readonly TheaterLights _lights;
private readonly Screen _screen;
private readonly PopcornPopper _popper;
public HomeTheaterFacade(Amplifier amp, DvdPlayer dvd, Projector projector, TheaterLights lights, Screen screen, PopcornPopper popper)
{
_amp = amp;
_dvd = dvd;
_projector = projector;
_lights = lights;
_screen = screen;
_popper = popper;
}
public void WatchMovie()
{
Console.WriteLine("Get ready to watch a movie");
_popper.On();
_popper.Pop();
_lights.Dim(5);
_screen.Down();
_projector.On();
_projector.WideScreenMode();
_amp.On();
_amp.SetDvd();
_amp.SetSurroundSound();
_amp.SetVolume(5);
_dvd.On();
_dvd.Play("Ready Player One");
}
public void EndMovie()
{
Console.WriteLine("Shutting movie theater down...");
_popper.Off();
_lights.On();
_screen.Up();
_projector.Off();
_amp.Off();
_dvd.Stop();
_dvd.Eject();
_dvd.Off();
}
}
}
测试
using FacadePattern.Equipments;
using FacadePattern.Facades;
namespace FacadePattern
{
class Program
{
static void Main(string[] args)
{
var facade = new HomeTheaterFacade(new Amplifier(), new DvdPlayer(), new Projector(), new TheaterLights(), new Screen(), new PopcornPopper());
facade.WatchMovie("Ready Player One");
facade.EndMovie();
}
}
}

来源
使用C# (.NET Core) 实现适配器模式 (Adapter Pattern) 和外观模式 (Facade Pattern)
外观模式,了解一二
更多推荐


所有评论(0)