设计模式学习4 - 行为模式

9 篇文章 0 订阅
 

不变模式

不变的对象更容易维护(尤其在多线程的情况下)。
大多数享元对象都是不变对象。

弱不变模式:子类可以变
强不变模式:子类也不可以变(所有的方法都是final的,或者该类本身就是final的--不能被继承)

java的String类就是一个不变类(对一个char[]的封装),其他封装类也是不变类。

一个不变对象的所有改值方法都应该返回一个新的该类的对象,而不能修改其内部的状态。

策略模式

动态的替换“算法”
重构:一个系统有很多类,他们的区别仅在于行为,策略模式可以让对象动态的选择其需要的行为。

优点:
    1 结合模板方法模式可以减少重复代码。
    2 动态的决定算法,这在单纯使用继承的时候是不能做到的
缺点:
    1 客户端必须知道这些策略类的存在
    2 可能出现很多的策略类或对象(也可以使用享元模式减少对象数量)

模板方法模式

重构:减少大方法,以及过多的条件转移

钩子方法应当以do开头,这是基本的命名规则


重构原则:尽量将行为移到高端,将状态移到低端

    1 根据行为而不是状态定义一个类
    2 类的行为应该划分到一组核心方法,这些方法可以方便的在子类替换
    3 将状态属性的确认推迟到子类,如果需要状态属性的时候可以使用get()方法,而子类可以替换该方法。
以上原则又助于抽象与实现充分分离,做到代码最大限度的服用



观察者模式

某些对象对某一主题关心,当这一主题发生变化时,这些对象可以自己更新自己



如果管理观察者对象的方法相同,则可以把聚集放在抽象subject里并添加管理方法,这时它不是接口应该是抽象类。

观察者模式与备忘录模式:

    观察者模式使用了备忘录模式

迭代器模式

实现数据模型内部遍历与业务逻辑的分离

责任链模式

责任链可能是链,环或者树的一部分

纯与不纯:

纯粹的责任链:一个Handler只有两种选择,承担责任或者推给下家。责任必须被完成
不纯:一个Handler可以承担部分责任,在把剩下的给下家。责任可以不被完成

命令模式


系统需要提供命令的undo和redo
对请求的命令排队--请求者可能已经不在了,但是命令可以持久化或序列化在远端执行
需要多种命令的组合(指定宏命令)



典型的例子:


    遥控器(Invoker),按键(Command),电视机(Receiver),用户把所有的命令都施加给遥控器,遥控器调用按键的命令,最后电视机执行命令。

轻命令:

    只提供了请求者和接受者之间的耦合
重命令:

    命令本身提供命令的实现,这时候就不需要接受者了

Undo和Redo


    命令类可以提供unExcute()方法,之前命令需要记录以下状态
    1 接受者执行的操作
    2 操作所需的参数
    3 操作之前接受者的状态,并且提供使接受者回到之前状态的方法

如果需要多层undo就要用一个数据结构存储这些状态,逆序执行就是undo顺序执行就是redo


缺点


可能产生过多的命令类

状态模式

一个对象的内部状态改变的时候,其行为也随之改变,看起来就像改变了他的类一样
就是基本操作都交给state对象来做(怎么有点像策略模式?)

状态的改变

可以由Context对象决定,也可以由State对象本身来判断其下一个State应该是谁

状态模式与策略模式


    1 这二者很相似,但是用意不同,如果环境类在生命周期有经常的状态变化,就用状态模式。如果具体策略不常变化,就用策略模式。
    2 策略模式通常环境类自己决定自己所需要的策略,而状态模式中环境类是被外在原因放入一个状态。
    3 策略模式中,环境类通常不告诉客户端自己所选择的策略,而状态模式中环境类通常是把自己的状态显示给客户端的。

访问者模式

如果系统具有稳定而又复杂的数据结构,使用访问者模式会让增加针对该数据结构的新的算法相对容易--迭代器只对单一层次的结构有效

双重动态分派(减少instance of 的判断分支),施加于节点之上的操作取决于访问者和节点本身的数据类型,而不只是二者其一
只有当节点的结构比较稳定的时候才适合使用访问者模式:当增加一个新的节点,所有访问者类都需要增加新的重载方法,这是很大的修改,违反了开闭原则

本质是用一次静态分派(重载)来取代了instance of 判断。--对类型的判断在visitor的具体实现中通过重载方法visitor(NodeA/B...)来取代,所以通过Java的静态分派就能找到需要调用的方法

ObjectStructure的action()方法遍历自己的Node并调用其accept(Visitor)方法。

objects = new ObjectStructure();
objects.add(new NodeA());
objects.add(new NodeB());
Visitor visitor = new VisitorA();
objects.action(vistior);

虽然这个示例中并没有出现复杂的树结构,但是访问者模式的强大之处就是可以处理树复杂的结构(可以参考合成模式)。


不要滥用模式


    只有在以下情况下才应该使用设计模式
        1 完全了解问题
        2 完全了解模式理论
        3 非常了解设计模式如何解决实际问题

调停者模式

避免同志之间的过度耦合,把多对多的关系转化为一对多

当一个同志发生改变的时候有哪些同志需要付出行动是由业务逻辑决定的。

调停者模式的缺点

虽然降低了同志之间的复杂性,但是增加了调停者内部的复杂性,通常这个调停者非常复杂。

虽然提供了同志类的复用性,然而是以牺牲调停者的复用性为代价的。

 

调停者与观察者

二者是很相像的,也是竞争的地位,也就是说选择了其中一种就意味着放弃另外一种,当然如果同志的数量不多的时候选用调停者模式比较容易看懂。



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值