设计原则和设计模式回顾

这次的模式回顾,做下简单的总结。

一、明确了重要的设计原则

面向接口多态组合的OOP:一定要正确使用设计原则和设计模式,要不断的重构设计,但是不能过度设计,需灵活运用。

1.系统要高内聚低耦合(顶层扇出比较大,中间扇出小,底层模块则有大扇入);数据和表现分离MVC模式,数据结构和算法分离; 微内核组件插件化设计脚本支持。

扇入:是指直接调用该模块的上级模块的个数。扇入大表示模块的复用程度高。
扇出:是指该模块直接调用的下级模块的个数。

2.依赖倒置原则和接口隔离原则(面向接口编程,使用继承和多态,臃肿接口是对接口的污染)

依赖倒置原则(高层和底层模块都应该依赖于抽象接口)。

3.开放-关闭原则和里氏原则(抽象定义好多态,对拓展开发,修改关闭,对变化进行封装;里氏原则是子类可以代替父类)。

4.迪米特法则和组合复用原则(维护通信中介,多个简单接口由于单个复杂接口,组合优于继承)。

5.单一职责原则,无论是对模块,类还是对函数。


二、创建型模式

没有回顾的:
SimpleFactory的广泛运用,FactoryMethod类似Bridge模式但关注问题领域不同,AbstractFactory需要

双方都很多变的情况才会使用。
SigleTon模式善于用static对象就可以了。
回顾了的:
Builder模式,SingleTon模式都是面向接口的,面向多态的,真正去搭建了这样的模式才叫

Builder,SingleTon模式,简单的Builder/SingleTon不能获得可拓展的好处。

三、结构型模式

1.Adapter模式

需要有客户接口Target和第三方库接口Adaptee,才能算Adapter模式;Adapter是为了包装Adaptee功能以符合Target的接口。所以Adapter总是继承Target的,可以继承也可以组合Adaptee接口。Adapter还有双向适配模式,也就是相互适配。


2.Bridge模式

是Bridge两端有各自维度或各自领域,例如:分离响应逻辑和业务实现,两端各自抽象和实现。使用时候再按照需要联系起来。Bridge和Target的区别是Bridge有两个业务领域,按需调用;Target只是对算法的封装,可以切换锦囊内对象的。


3.Composite模式

意在组合多个子类对象作为一个复杂对象给客户无论是节点对象还是叶子对象都统一处理,方便了对象的构建。

4.Decorate模式

是对一个对象的修饰或者多次修饰提供给客户。游戏中主角常用Plugin插件对象装饰主角,如果关系不是那么紧密的可以用Plugin装饰,如果是和主角属性关系紧密的那么需要Decorate可以更好的复用被修饰体的数据,提供更好的修饰,避免产生太多的子类。


5.Proxy模式

也是基于接口的,Proxy也需要对客户提供的统一接口;简单的委托没有Proxy模式拓展性好。

6.FlyWeight模式

也是基于接口的,关联被享元的父类指针,对外提供查询对象的接口。

7.Facade模式

是单向关联子系统的,Mediator才是提供和子系统双向关联的,Facade模式会破坏开放-关闭原则,通过抽象Facade模式可以改善这种情况,对外提供稳定的接口,Facade在子类中变化。


四、行为模式

1.Template模式

多态继承复用,Template更加耀眼的方面是模板,通过Template基类模板定义一些调用框架逻辑,用户子类只需要根据自己的业务逻辑简单设置就可以了。Strategy对于提供多种业务算法来说更加灵活,他们都是可以存在多个对象多种业务算法的。但是Template在为了更多在父类处理,或者用父类定义调用框架时候却更有用。

2.Strategy模式

策略锦囊模式,只是一个维度(算法)的抽象接口,Strategy可以选择不同的算法替换或者业务替换,Strategy本身并不抽象,而Bridge却需要Bridge两端都要抽象接口。

3.State模式

双向关联,是对自身状态的分离出状态类且维护管理各个状态类,状态类有状态关心的状态处理函数,状态类关联Context用于跳转状态和回调它来执行状态的处理函数。

和Strategy模式区别:区别是Strategy关注一对多算法,State是分离出状态和状态处理函数。

和Commmand模式区别:是State是数据主体类分离出来的,Command是命令发出者和接收者之间插入的一个中转,要求Command有接口类,Receiver也有接口类,InvokerControl也有接口类。

和Chain of Rain区别:状态模式是让各个状态对象自己知道其下一个处理的对象是谁。而职责链模式中的各个对象并不指定其下一个处理的对象到底是谁,只有在客户端才设定。


State状态模式在多个content可以对应一个State状态模式下,才能真正的降低冗余,利于可维护性。

4.Observer模式

单向/双向关联,Subject是数据主体类,Observer是观察者类,不仅Observer要有统一的基类接口,Subject也要有基类接口,且Observer子类是可以关联Subject子类的,保存一份具体的Subject状态,当状态改变时候或者数据改变时候才回调到Observer中提高性能。

5.Mediator模式

双向关联,迪米特法则的经典应用网状结构简化为星型结构,不仅仅是维护了各个相关类那么简单,Mediator主要是定义了各个子类之间通信的映射(map或者数组)规则,当一个逻辑类注册了Mediator子类后,Send方法内用mediatorObj->Operation(this)发送消息会跳转到相应的其它逻辑类调用,且Mediator有接口和子类定义了映射和操作方法给逻辑类用。逻辑基类Colleague,拥有Mediator对象,定义Send方法,Notify方法(定义了被调用时候的处理),他们是双向调用的。

和Facade模式区别:Facade是单向地去管理内部逻辑子类,Mediator与逻辑子类间是双向关联的。
和State模式区别:Stated的数据主体类是定义各个状态子类,主体类并不了解状态间的转换,状态转换被放置到了状态子类中;Mediator定义了各个逻辑子类间的映射调用关系,State调用驱动发出是数据主体类设置了状态后发出的,Mediator的调用驱动是由逻辑子类发出的。

6.Visitor模式

双向关联/依赖:Visitor模式真正含义:Visitor模式-数据主体需要稳定/相互关联三部分组成实现双分派或多分派 。

     第一个部分是数据元素部分必须是一个稳定的结构,抽象出来的接口Accept方法是给ObjectStruct使用的,关联了访问者模式的抽象方法,不同的数据元素会调用访问者接口不同的方法(一般访问者是为数据元素定制的,也就是访问者进来访问,有多少个元素会产生多少个分派处理)。

     第二部分访问者接口中的方法数量是对应数据元素的统一了接口,为了给数据元素调用且子类能够实现不同的操作,访问者子类会关联数据元素,是为了看是否要根据数据元素的状态进行操作限定。
     第三部分是对象结构部分,需要先将数据元素注册到对象结构里面,然后对象结构执行动作方法(以访问者作为参数传入),对象结构里面的数据元素会选择访问者不同的动作进行表现。
    与Iterator模式,由于访问者模式需要对对象结构进行操作,而对象结构本身是一个元素对象的集合,因此访问者模式经常需要与迭代器模式联用,在对象结构中使用迭代器来遍历元素对象。
    与Composite模式,在访问者模式中,元素对象可能存在容器对象和叶子对象,因此可以结合组合模式来进行设计。

7.Iterator模式

双向关联/聚合,Aggregate类是容器类需要将特定的迭代器创建出来返回Iterator基类指针,Iterator基类接口定义了访问容器的方法,Iterator特定子类定义了针对不同的聚合容器的实现遍历操作返回容器元素,这样容器返回的Iterator就可以遍历自己元素。也就是遍历操作从容器分离出来了,因为每一种类型的容器需要提供不同的Iterator子类,所以这种方式也会大量增加类的数量,当有稳定数量的容器(或者数据主体)时候才采用这样的分离方法,当然不仅仅是遍历其它类型的操作分离也是 可以的。


8.Memento模式

单向关联,不仅仅是数据主体创建一个备忘录类,需要保存的时候保存到备忘录中,需要恢复数据状态的时候从备忘录中得到(可以按条件查询获得不同的状态);而且更好的方式是要一个备忘录的管理者类,通过备忘录的管理者得到不同的备忘录类,更好的将备忘录类接口抽象,提供多个备忘录类时候易于拓展。


9.Interpreter模式

单向关联,对频繁出现需要处理的事情抽象为一个迷你语言-脚本,然后针对每个语句含义写一个解释器类,解释器有终结解释器不关联解释器基类解释结束,非终结解释器需要关联解释器基类(其实是其它子解释器)解释不了的传递下去解释。

Interpreter和Chain of Resposibility区别,Command区别,见Command模式,和Chain of

Resposibility模式。
 

10.Command模式

是在命令发出者和接受者之间插入了一个命令,命令需要接受者初始化,命令类注册给命令发出者,命令发出者直接执行命令接口抽象的Excute方法就可以了,所以命令模式只是命令的转发解耦作用;而解释器模式是将一种动作声明为命令,然后解释命令的含义,尤其是可以多个动作可以一起发出的时候。


11.Chain of Resposibility模式

Chain of Resposibility是抽象出Handle基类,拥有设置下一个处理者函数(但子类不设置),有当前的处理函数,处理不了就交给下一任,也可以有默认处理函数全部处理不了就交给它,Chain of Resposibility和状态模式的区别是状态子类之间是知道对方的且有状态管理类,但是Chain of Resposibility子类之间不知道对方且没有管理类(也可以抽取出来),只有客户端知道下一任处理者是谁(客户端需要处理调整责任链顺序)。Interpreter是区分叶子节点和枝节点,且都是可以解释文本内容的(Interpreter是一个内容多个解释器,Chain of Resposibility是一个内容一个处理类),Interpreter不拥有默认解释者。


      当设计一个游戏主角状态时候如果内部状态间切换比较多且限制较多那么用State模式,如果需要执行一个命令或多个连续命令分别解释那么可以用Interpreter模式,如果都是单一的命令有一个或多个命令接受者时候需要用Command模式。因为一个命令只能对一个主角且主角状态限制比较多,且不需要多个命令一起解释,所以对主角执行一个命令,那么用状态模式比较好,状态管理器有各个状态的实例,状态管理器设置一个状态执行动作,然后管理器再执行需要的动作,也就是在当前状态下执行需要的动作,状态子类会在执行动作时候会调用状态管理类设置下一个状态子类,且调用状态管理类来执行。如果状态之间的关系因为引入一个新的状态而变更太大,那么还是需要C风格的枚举常量较好,没有引入复杂的模式,大家也看得明白透彻,改动也是差不多量的。

五、总结:

 架构设计中的设计原则,设计模式的应用,可以说比较简单,直接应用就可以了。也可以说比较复杂,原因有:

1.里面有各种模式的选择问题(需要对各个模式和它们之间的差别有清晰的了解)。

2.正确使用问题(首先需要对每个模式有透彻的了解,领悟接口编程思想,开放关闭原则,特别是前提条件,和使用方式的了解)。

3. 灵活运用问题(标准设计模式是很多局限性的,如何根据问题情景进行恰当修改或改进,如果在多个模式之间结合形成更贴切的模式),需要不断的去学习不断去运用提高架构设计能力。

4.忠告:

设计模式是重构必经之路,但不是最终的目标。好的代码会产生好的代码,坏的代码会产生坏的代码。不要过度设计,不必为了模式而模式,有时候,一旦遇到某个三种不同的计算,就想使用strategy模式,而事实上,简单地条件表达式编程就足够了,而也易于理解。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值