一、什么是外观模式
为子系统中的一组接口提供一个一致的界面
用一个高层接口,统一了一组底层接口,和外界交互更加方便,外部应用程序不需要关心内部子系统的具体细节,大大降低程序的复杂度,提高程序可维护性.
UML图
Facade:外观类,负责将子系统的功能接口统一到一个接口
SubsysytemA : 子系统,不与客户端直接联络
Client : 只和外观类联络,减少耦合性
二、适用场景
各种代办事宜,这个事宜其实是个流程,比如你去餐馆点菜,只需要用手机扫码点菜, 餐馆服务员、 厨房大厨、帮工就都会通过这个点餐APP收到菜品,然后开始制作,客人不需要知道这个菜都有哪些人参与。再就是在一个旧的系统基础上去添加新功能,旧的系统已经很难修改和扩展了,这样在交互的时候留出接口统一到一个外观类接口,然后新人只需要编写自己的功能类然后和这个外观类交互。
三、优缺点
优点
减少系统互相依赖,减少耦合性
提高灵活性,可复用性高
提高安全性,只和朋友联络
缺点
增加了一层中介层
不符合开闭原则
四、大话中的例子
买股票还是买基金的问题: 买股票就是耦合太高,个人需要和所有想要买得股票耦合,调研学习,然后只单只的购买。但是基金不一样,基金个人只需要关注一只基金,这只基金会去和市面上的股票证券等金融类型打交道,对个人来说耦合性大大降低。比如有股票A、股票B、股票C、证券A、证券B,如果没有外观类,我想买 股票A、股票C、证券B,那就需要和这几个对象关联,耦合性很高,有了外观类, 外观 类关联所有股票、证券, 想要ACB还是BCA,都写成一个函数中, 外界只需要调用这个函数就行了。
五、我的例子
using System;
namespace FacadeMode
{
class Program
{
static void Main(string[] args)
{
TaskAgency taskAgency = new TaskAgency();//找到委托
taskAgency.OrganizeGroupByTask(TaskLevel.C);//我要你执行一个C级任务
Console.WriteLine("=====================");
taskAgency.OrganizeGroupByTask(TaskLevel.S);//我要你执行一个S级任务
Console.ReadKey();
}
}
/// <summary>
/// 任务委托机构
/// </summary>
public class TaskAgency
{
Shimooshi naruto = new Shimooshi("鸣人");
Shimooshi sasuke = new Shimooshi("佐助");
Uenin neji = new Uenin("宁次");
Uenin nara = new Uenin("鹿丸");
Nakanin kakashi = new Nakanin("卡卡西");
Nakanin kay = new Nakanin("凯");
TaskGroup taskGroup;
public void OrganizeGroupByTask(TaskLevel taskLevel)
{
Console.WriteLine("执行{0}级任务", taskLevel);
switch (taskLevel)
{
case TaskLevel.D:
case TaskLevel.C:
taskGroup = new CLevelGroup(neji, naruto);
break;
case TaskLevel.B:
case TaskLevel.A:
case TaskLevel.S:
taskGroup = new SLevelGroup(kakashi, kay);
break;
}
taskGroup.GroupJionTask();
}
}
/// <summary>
/// 忍者抽象类
/// </summary>
public abstract class Ninha
{
protected NinhaLevel ninhaLevel;
string _name;
public Ninha(string name)
{
this._name = name;
}
public void JoinTaskForce()
{
Console.WriteLine("{0}加入任务小组", _name);
}
}
/// <summary>
/// 下忍
/// </summary>
public class Shimooshi : Ninha
{
public Shimooshi(string name) : base(name)
{
ninhaLevel = NinhaLevel.shimooshi;
}
}
/// <summary>
/// 中忍
/// </summary>
public class Uenin : Ninha
{
public Uenin(string name) : base(name)
{
ninhaLevel = NinhaLevel.uenin;
}
}
/// <summary>
/// 上忍
/// </summary>
public class Nakanin : Ninha
{
public Nakanin(string name) : base(name)
{
ninhaLevel = NinhaLevel.nakanin;
}
}
/// <summary>
/// 任务小组抽象类
/// </summary>
public abstract class TaskGroup
{
protected Ninha[] ninhas = new Ninha[2];
public void GroupJionTask()
{
for (int i = 0; i < ninhas.Length; i++)
{
ninhas[i].JoinTaskForce();
}
}
}
public class SLevelGroup : TaskGroup
{
public SLevelGroup(Nakanin nakanin1, Nakanin nakanin2)
{
ninhas[0] = nakanin1;
ninhas[1] = nakanin2;
}
}
public class CLevelGroup : TaskGroup
{
public CLevelGroup(Uenin uenin, Shimooshi shimooshi)
{
ninhas[0] = uenin;
ninhas[1] = shimooshi;
}
}
public enum NinhaLevel
{
shimooshi,//下忍
uenin,//中忍
nakanin,//上忍
}
public enum TaskLevel
{
D,
C,
B,
A,
S,
}
}
运行结果
PS:学了设计模式总会很刻意的去弄各种设计模式,在我的案例里面,任务小组的组员是固定的,其实应该灵活一点,比如把所有忍者按忍级分个组,接到任务时,任务的分配首先符合忍者等级的需求,再在同等级忍者里面顺位挑选之类的,而不是直接给定一个人去执行, 任务按等级ABCD是抽象的,所接受任务的忍者也该是抽象的,而不是具体的某个忍者.这里除了使用外观模式,还使用了策略模式,按任务等级分组就是策略,哪两个人为一个小组就是算法, 还用了简单工厂模式, 根据不同任务等级,直接调起对应的任务小组.很多举的例子都是为了例子而例子,在实际开发需求中不一定按着这个套路执行,我们应该有举一反三的能力,重要的吸收里面的设计思想,为什么要用这种模式,适用于什么情况.
来源:CSDN
作者:彩色墨水
链接:https://blog.csdn.net/weixin_44186849/article/details/103489197