大话设计模式:外观模式

↘锁芯ラ 提交于 2019-12-13 03:58:09

一、什么是外观模式

为子系统中的一组接口提供一个一致的界面

用一个高层接口,统一了一组底层接口,和外界交互更加方便,外部应用程序不需要关心内部子系统的具体细节,大大降低程序的复杂度,提高程序可维护性.

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是抽象的,所接受任务的忍者也该是抽象的,而不是具体的某个忍者.这里除了使用外观模式,还使用了策略模式,按任务等级分组就是策略,哪两个人为一个小组就是算法, 还用了简单工厂模式, 根据不同任务等级,直接调起对应的任务小组.很多举的例子都是为了例子而例子,在实际开发需求中不一定按着这个套路执行,我们应该有举一反三的能力,重要的吸收里面的设计思想,为什么要用这种模式,适用于什么情况.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!