博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Facade外观模式(结构性模式)
阅读量:6263 次
发布时间:2019-06-22

本文共 3806 字,大约阅读时间需要 12 分钟。

1、系统的复杂度

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

常规的设计如下:

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

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

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

 

2、问题

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

 

3、解决方案

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

#region 坦克系统组成        ///         /// 引擎类        ///         internal class Engine        {            public void EngineActionA() { }            public void EngineActionB() { }        }        ///         /// 车轮        ///         internal class Wheel        {            public void WheelActionA() { }            public void WheelActionB() { }        }        ///         /// 控制器        ///         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();            ///             /// 坦克的启动功能,完成引擎、控制器的初始化.            ///             public void Start()            {            }            ///             /// 坦克的停止功能,完成引擎、控制器的停止            ///             public void Stop()            {            }        }

客户端调用代码如下:

///         /// 游戏系统        ///         public class GameSystem        {            private TankFacade tankFacade = null;            ///             /// 开始游戏            ///             public void Run()            {                TankFacade facade = new TankFacade();                facade.Start();            }            ///             /// 结束游戏            ///             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模式注重稳定接口的情况下,为接口扩展功能.

 

转载地址:http://jxzpa.baihongyu.com/

你可能感兴趣的文章
Android ROM开发--ubuntu下编译CyanogenMod生成SDK
查看>>
Cocos2d下TexturePacker2.3版会给iphone, ipad通用版带来的问题
查看>>
全新的互动广告牌,待遇男女有别
查看>>
Language modeling meets inference networks
查看>>
mvc3学习之--安装
查看>>
Html5 学习系列(一)认识HTML5
查看>>
弗洛伊德算法
查看>>
((ios开发学习笔记 十))代码实现自定义TableView
查看>>
WPF 之转换器
查看>>
mongo-update 操作(2)
查看>>
添加列前先检查
查看>>
[Step By Step]SAP HANA PAL KNN 近邻预测分析K- Nearest Neighbor编程实例KNN
查看>>
oracle set命令详解
查看>>
可变的数据变量一定要初始化之后才能再用
查看>>
浅用block 转
查看>>
HDU 3032 Nim or not Nim?(博弈,SG打表找规律)
查看>>
Android soundpool初探
查看>>
c#操作access,update语句不执行的解决办法
查看>>
艺术(良质)的代价--读禅与摩托车维修艺术
查看>>
Linux 比较重要且难掌握命令 集合
查看>>