03.外观模式
外观式定义
为子系统中的一组接口提供一个一致的界面,Facade 模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
界面
在这里提到的界面,主要指的是从一个组件外部来看这个组件,能够看到什么,这就是这个组件的界面,也就是所说的外观。
接口
在这里提到的接口,主要指的是外部和内部交互的这么一个通道,通常是指一些方法,可以是类的方法,也可以是 interface 的方法。也就是说,这里所说的接口,并不等价于 interface,也有可能是一个类。
外观模式的结构和说明
Facade
定义子系统的多个模块对外的高层接口,通常需要调用内部多个模块,从而把客户的请求代理给适当的子系统对象。
模块
接受 Facade 对象的委派,真正实现功能,各个模块之间可能有交互。
但是请注意,Facade 对象知道各个模块,但是各个模块不应该知道 Facade 对象。
代码示例
using System;
namespace NetCore3Console.Facade
{
/// <summary>
/// A模块的接口
/// </summary>
public interface AModuleApi
{
/// <summary>
/// 示意方法,A模块 对外的一个功能方法
/// </summary>
void TextA();
}
public class AModuleImpl : AModuleApi
{
public void TextA()
{
Console.WriteLine("现在在A模块里面操作testA方法");
}
}
/// <summary>
/// B模块的接口
/// </summary>
public interface BModuleApi
{
/// <summary>
/// 示意方法,A模块 对外的一个功能方法
/// </summary>
void TextB();
}
public class BModuleImpl : BModuleApi
{
public void TextB()
{
Console.WriteLine("现在在B模块里面操作testB方法");
}
}
/// <summary>
/// C模块的接口
/// </summary>
public interface CModuleApi
{
/// <summary>
/// 示意方法,A模块 对外的一个功能方法
/// </summary>
void TextC();
}
public class CModuleImpl : CModuleApi
{
public void TextC()
{
Console.WriteLine("现在在B模块里面操作testC方法");
}
}
/// <summary>
/// 外观对象
/// </summary>
public class Facade
{
/// <summary>
/// 示意方法,满足客户需要的功能
/// </summary>
public void Test()
{
//在内部实现的时候,可能会调用到内部的多个模块
AModuleApi a = new AModuleImpl();
a.TextA();
BModuleApi b = new BModuleImpl();
b.TextB();
CModuleApi c = new CModuleImpl();
c.TextC();
}
}
}
模式讲解
外观模式的目的
外观模式的目的不是给子系统添加新的功能接口,而是为了让外部减少与子系统内多个模块的交瓦,松散耦合,从而让外部能够更简单地使用子系统。
外观模式的实现
Facade的实现
对于一个子系统而言,外观类不需要很多,通常可以实现成为一个单例。也可以直接把外观中的方法实现成为静态的方法,这样就可以不需要创建外观对象的实例而直接调用,这种实现相当于把外观类当成一个辅助工具类实现。
Facade的方法实现
Facade的方法实现中,一般是负责把客户端的请求转发给子系统内部的各个模块进行处理,Facade 的方法本身并不进行功能的处理,Facade 的方法实现只是实现一个功能的组合调用。
思考外观模式
外观模式的本质
外观模式的本质是:封装交互,简化调用。
Facade 封装了子系统外部和子系统内部多个模块的交互过程,从而简化了外部的调用。通过外观,子系统为外部提供一些高层的接口,以方便它们的使用。
对设计原则的体现
外观模式很好地体现了“最少知识原则”。
外观模式就是新添加了个Facede类,在这里面组合调用其他方法呀。