外观模式
本篇博客将介绍外观模式,外观模式是一种使用频率非常高的设计模式,它通过引入一个外观角色来简化客户端与子系统之间的交互,为复杂的子系统调用提供一个统一的入口,使子系统与客户端的耦合度降低,且客户端调用非常方便。
模式分类
结构型设计模式。
模式产生的原因
在软件开发中,当我们需要访问一系列子系统来完成一个功能,此时由于涉及的类比较多,导致使用时代码就会比较复杂。而这些需要交互的类又经常会作为一个整体出现,此时如果有一个类可以帮助我们对这一系列的类完成调用就好了,于是我们引入这样一个类,这个类就是这个功能的一个外观类。
模式灵感的来源
在现实生活中,如果说我们想要喝一杯茶,我们可以选择自己泡一杯茶,这就需要我们知道泡茶的流程,以及我们需要自行准备茶具。但是如果我们去茶馆喝茶,我们只需要和服务员说我们想和什么茶即可,服务员会去帮我们泡茶并将泡好的茶端上来,这里的服务员就是泡茶流程的一个外观角色,我们不再需要自己泡茶,直接通知服务员。
模式类图
由上图可知,外观模式基本上有2个对象构成:
BaseFacade(抽象外观类):
外观类的抽象接口,也可以是抽象类,不是必须要有的,当然如果你的系统中包含一个这样的模块,会增加你系统的灵活性。
Facade(具体外观类):
客户端可以调用它的方法,在外观角色中可以知道相关的子系统的功能和责任;在正常情况下,他将所有从客户端发来的请求委派到相应的子系统,传递相应的子系统对象处理结果。
代码实现
我们通过一个例子来实现外观模式的代码:
在计算机主机(Mainframe)中,只需按下主机的开机键(On()),即可调用其他硬件设备和软件的启动方法,比如内存(Memory)的自检(Check())、CPU运行的(Run())、硬盘(HardDisk)的读取(Read())、操作系统(OS)的载入(Load())等,请使用外观模式模拟该过程。
BaseFacade抽象外观类:
namespace Facade.Facade.Question5
{
public abstract class BaseFacade
{
public abstract void On();
}
}
Mainframe主机类:
namespace Facade.Facade.Question5
{
public class MainFrame : BaseFacade
{
private CPU _myCpu;
private HardDisk _myHardDisk;
private Memory _myMemory;
private OperationSystem _myOperationSystem;
public void SetCpu(CPU cpu)
{
_myCpu = cpu;
}
public void SetHardDisk(HardDisk hardDisk)
{
_myHardDisk = hardDisk;
}
public void SetMemory(Memory memory)
{
_myMemory = memory;
}
public void SetOperationSystem(OperationSystem operationSystem)
{
_myOperationSystem = operationSystem;
}
public override void On()
{
_myCpu.Run();
_myMemory.Check();
_myHardDisk.Read();
_myOperationSystem.Load();
}
}
}
CPU类:
using System;
namespace Facade.Facade.Question5
{
public class CPU
{
public void Run()
{
Console.WriteLine("CPU运行");
}
}
}
HardDisk硬盘类:
using System;
namespace Facade.Facade.Question5
{
public class HardDisk
{
public void Read()
{
Console.WriteLine("硬盘读取");
}
}
}
Memory内存类:
using System;
namespace Facade.Facade.Question5
{
public class Memory
{
public void Check()
{
Console.WriteLine("内存自检");
}
}
}
OS操作系统类:
using System;
namespace Facade.Facade.Question5
{
public class OperationSystem
{
public void Load()
{
Console.WriteLine("操作系统载入");
}
}
}
外观模式总结
外观模式的优点:
- 他对客户端屏蔽了子系统组件,减少了客户端所需要的对象数目,并使得子系统使用起来更加方便。
- 它实现了子系统与客户端之间的松耦合关系,这使得子系统的变化不会影响到调用它的客户端,只需要调整外观类即可。
外观模式的缺点:
- 外观模式并不能很好的限制客户端直接使用子系统的类,如果对客户端访问子系统类做了太多的限制,则会减少可变性和灵活性。
- 如果设计不当,增加子系统可能会修改外观类的源代码,违背了开闭原则。