概念:
外观(Facade)模式又叫作门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式对外有一个统一接口,外部应用程序不用关心内部子系统的具体细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
主要解决:
降低访问复杂系统的内部子系统时的复杂度,简化客户端与之的接口。
意图:
为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
外观(Facade)模式是“迪米特法则”的典型应用,它有以下主要优点。
- 减少系统相互依赖。
- 提高灵活性。
- 提高了安全性。
外观(Facade)模式的主要缺点如下。
- 不符合开闭原则,如果要修改某一个子系统的功能,通常外观类也要一起修改。
- 没有办法直接阻止外部不通过外观类访问子系统的功能,因为子系统类中的功能必须是公开的(根据需要决定是否使用internal访问级别可解决这个缺点,但外观类需要和子系统类在同一个程序集内)。
实现类图
抽象基类:
public abstract class 饭店
{
abstract public void SetMeal();
}
接口类:
public interface 支持外卖
{
public void 送餐();
}
子类:
using System;
public class 火锅店 : 饭店
{
public override void SetMeal()
{
Console.WriteLine("火锅");
}
}
using System;
public class 烤肉店 : 饭店, 支持外卖
{
public override void SetMeal()
{
Console.WriteLine("烤肉");
}
public void 送餐()
{
Console.WriteLine("立刻送餐");
}
}
引入外观类:
using System;
public class 外卖APP
{
private 火锅店 n = new 火锅店();
private 烤肉店 m = new 烤肉店();
public void 外卖送餐(饭店 a)
{
a.SetMeal();
if (a is 支持外卖)//判断该饭店是否支持外卖
{
(a as 支持外卖).送餐();//转换为支持外卖的类型
}
else
{
Console.WriteLine("该饭店不支持外卖");
}
}
}
测试
using System;
class Program
{
static void Main(string[] args)
{
外卖APP m = new 外卖APP();
m.外卖送餐(new 烤肉店());
m.外卖送餐(new 火锅店());
Console.Read();
}
}
输出示例:
外观模式的使用场景
- 设计初期阶段,应该有意识的将不同层分离,层与层之间建立外观模式;
- 开发阶段,子系统越来越复杂,增加外观模式提供一个简单的调用接口;
- 维护一个大型遗留系统的时候,可能这个系统已经非常难以维护和扩展,但又包含非常重要的功能,为其开发一个外观类,以便新系统与其交互。