zoukankan      html  css  js  c++  java
  • Facade外观模式(结构性模式)

    1、系统的复杂度

    需求:开发一个坦克模拟系统用于模拟坦克车在各种作战环境中的行为,其中坦克系统由引擎、控制器、车轮等各子系统构成.然后由对应的子系统调用.

    常规的设计如下:

            #region 坦克系统组成
            /// <summary>
            /// 引擎类
            /// </summary>
            public class Engine
            {
                public void EngineActionA() { }
    
                public void EngineActionB() { }
            }
    
            /// <summary>
            /// 车轮
            /// </summary>
            public class Wheel
            {
                public void WheelActionA() { }
    
                public void WheelActionB() { }
            }
    
            /// <summary>
            /// 控制器
            /// </summary>
            public class Controller
            {
                public void ControllerActionA() { }
    
                public void COntrollerActionB() { }
            } 
            #endregion
    
            /// <summary>
            /// 游戏系统
            /// </summary>
            public class GameSystem
            {
                /// <summary>
                /// 引擎初始化类
                /// </summary>
                public class EngineInit
                {
                    /// <summary>
                    /// 引擎初始化,并将控制权交给控制器
                    /// </summary>
                    public void Init()
                    {
                        var engine = new Engine();
                        var controller = new Controller();
                    }
                }
    
                /// <summary>
                /// 车轮初始化类
                /// </summary>
                public class WheelInit
                {
                    /// <summary>
                    /// 车轮初始化,并将控制权交给控制器
                    /// </summary>
                    public void Init()
                    {
                        var engine = new Wheel();
                        var controller = new Controller();
                    }
                }
            }

    ok,这是最简单的实现,完成了游戏系统对坦克系统的调用,将上面的系统调用抽象成一张构成图,如下:

    可以发现,坦克系统的各个组成部分,柔和到了游戏系统的各个类型中,这种设计一旦坦克的组成部分发生变化,所造成的维护成本是十分昂贵的!

    2、问题

    组件(坦克系统)的客户端调用程序(系统系统)和组件中各种复杂的子系统之间产生了过多的耦合,随着外部客户程序和组件各子系统的演化,这种耦合产生的维护成本十分昂贵.

    3、解决方案

    必须抽象出一层接口,这层接口需要将坦克系统进行抽象,并告诉游戏客户端哪些功能,是它可以调用的,而不是让系统系统自己去调用坦克系统的组件来实现相关的功能,将组件系统(坦克系统)和外部调用客户程序(游戏系统)的变化之间的依赖解耦.将这种变化成本交给这层接口来承担.

            #region 坦克系统组成
            /// <summary>
            /// 引擎类
            /// </summary>
            internal class Engine
            {
                public void EngineActionA() { }
    
                public void EngineActionB() { }
            }
    
            /// <summary>
            /// 车轮
            /// </summary>
            internal class Wheel
            {
                public void WheelActionA() { }
    
                public void WheelActionB() { }
            }
    
            /// <summary>
            /// 控制器
            /// </summary>
            internal class Controller
            {
                public void ControllerActionA() { }
    
                public void COntrollerActionB() { }
            }
            #endregion
    
            public class TankFacade
            {
                //注入相关坦克系统的组件,如果引擎、车轮这些可能会有风格的变化,可以考虑使用工厂模式来实现注入
                Engine[] Engines = new Engine[6];
                Wheel[] Wheels = new Wheel[6];
                Controller Controller = new Controller();
    
                /// <summary>
                /// 坦克的启动功能,完成引擎、控制器的初始化.
                /// </summary>
                public void Start()
                {
    
                }
    
                /// <summary>
                /// 坦克的停止功能,完成引擎、控制器的停止
                /// </summary>
                public void Stop()
                {
    
                }
            }

    客户端调用代码如下:

            /// <summary>
            /// 游戏系统
            /// </summary>
            public class GameSystem
            {
                private TankFacade tankFacade = null;
                /// <summary>
                /// 开始游戏
                /// </summary>
                public void Run()
                {
                    TankFacade facade = new TankFacade();
                    facade.Start();
                }
    
                /// <summary>
                /// 结束游戏
                /// </summary>
                public void Stop()
                {
                    if(tankFacade!=null)
                        tankFacade.Stop();
                    throw new Exception("引擎未启动,无法停止!");
                }
            }

    通过TankFacade类,将坦克系统的组件集成到里面,提供给游戏系统它所需要的功能,很好的实现了客户端调用系统依赖与坦克组件的问题,完成了解耦.解耦后的结构图如下:

    4、要点

    (1)、从客户程序的角度来看,Facade模式补不仅简化了整个组件系统的接口,同时对于组件内部与外部客户程序来说,达到了一种解耦的效果,内部子系统的变化不会影响到Facade接口的变化.

    (2)、Facade模式更注重从架构的层次去看待整个系统,而不是单个类的层次,更多的时候是一种架构设计模式.

    (3)、Facede模式与Apater模式、Bridge模式、Decorator模式的区别,Facede模式注重简化接口,Apater注重转换接口(将现有接口转换成客户需要的接口),Bridge模式接口的分离(即系统按照两个维度及以上的变化适合使用Bridge模式),Decorator模式注重稳定接口的情况下,为接口扩展功能.

  • 相关阅读:
    jira:7.12.3版本搭建(破解版)
    traefik添加多证书
    人肉分析sorted(lst, key=lambda x: (x.isdigit(), x.isdigit() and int(x) % 2 == 0, x.islower(), x.isupper(), x))过程
    jquery实现checkbox全选/反选/取消
    k8s简单集群搭建
    第十二周编程总结
    第十周作业
    第九周编程总结
    第七周编程总结
    第五周编程总结
  • 原文地址:https://www.cnblogs.com/GreenLeaves/p/9821999.html
Copyright © 2011-2022 走看看