设计模式——行为型模式

设计模式——行为型模式

策略模式

当我们写代码时总会遇到一种情况,就是我们会有很多的选择,由此衍生出很多的if…else,或者 case。如果每个条件语句中包含了一个简单的逻辑,那还比较容易处理;但如果在一个条件语句中又包含了多个条件语句,就会使得代码变得臃肿,维护的成本也会加大,这显然违背了开放封闭原则。

定义:定义一系列的算法,把每一个算法封装起来,并且使它们可相互替换。策略模式使得算法可独立于使用它的客户而独立变化。

在策略模式中有如下角色:

  • Context:上下文角色,用来操作策略的上下文环境,起到承上启下的作用,屏蔽高层模块对策略、算法的直接访问。
  • Stragety:抽象策略角色,策略、算法的抽象,通常为接口。
  • ConcreteStragety:具体的策略实现。

简单实现

张无忌作为一个大侠会遇到很多对手,如果每遇到一个对手他都用自己最厉害的武功去应战,这显然是不明智的。于是张无忌想出了3种应战的策略,分别对付3个实力层次的对手。

定义策略接口

策略接口有一个fighting方法用于战斗:
在这里插入图片描述
具体策略实现

分别定义3个策略来实现策略接口,用来对付3个实力层次的对手,代码如下所示:
在这里插入图片描述
上下文角色

上下文角色的构造方法包含了策略类,通过传进来不同的具体策略来调用不同策略的fighting方法,如下所示:
在这里插入图片描述
客户端调用

张无忌对不同实力层次的对手,采用了不同的策略来应战。为了举例,这里省略了对不同实力层次进行判断的条件语句,代码如下所示。
在这里插入图片描述
上面只是举了一个简单的例子,其实情况会很多:比如遇到普通的对手,也不能完全用圣火令神功;比如当遇到周芷若和赵敏时就需要手下留情,采用太极剑;又比如遇到强劲的对手张三丰,由于是自己师公,也不能使用乾坤大挪移。类似这样的情况会很多,这样在每个策略类中可能会出现很多条件语句。但是试想一下如果我们不用策略模式来封装这些条件语句,那么可能会导致一个条件语句中又包含了多个条件语句,这样会使代码变得臃肿,维护的成本也会加大。

使用场景和优缺点

使用场景

  • 对客户隐藏具体策略的实现细节,彼此完全独立。
  • 针对同一类型问题的多种处理方式,仅仅是具体行为有差别时。
  • 策略模式将相关的条件分支移入它们各自的 Strategy 类中,以代替这些条件语句。

优点

  • 使用策略模式可以避免使用多重条件语句。多重条件语句不易维护,而且易出错。
  • 易于拓展。当需要添加一个策略时,只需要实现接口就可以了。

缺点

  • 每一个策略都是一个类,复用性小。如果策略过多,类的数量会增多。

观察者模式

观察者模式又被称为发布-订阅模式,属于行为型设计模式的一种,是一个在项目中经常使用的模式。它的定义如下。

定义:定义对象间一种一对多的依赖关系,每当一个对象改变状态时,则所有依赖于它的对象都会得到通知并被自动更新。

在观察者模式中有如下角色:

  • Subject:抽象主题(抽象被观察者)。抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
  • ConcreteSubject:具体主题(具体被观察者)。该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
  • Observer:抽象观察者,是观察者的抽象类。它定义了一个更新接口,使得在得到主题更改通知时更新自己。
  • ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。

简单实现

关于观察者模式这种发布-订阅的形式,我们可以拿微信公众号来举例。假设微信用户就是观察者,微信公众号是被观察者。

抽象观察者

里面只定义了一个更新的方法:
在这里插入图片描述
具体观察者

微信用户是观察者,里面实现了更新的方法
在这里插入图片描述
抽象观察者

抽象被观察者,提供了attach、detach、notify三个方法
在这里插入图片描述
具体被观察者

微信公众号是具体主题(具体被观察者),里面存储了订阅该公众号的微信用户,并实现了抽象主题中的方法
在这里插入图片描述
客户端调用
在这里插入图片描述

使用场景及优缺点

使用场景

  • 关联行为场景。
  • 事件多级触发场景。
  • 跨系统的消息交换场景,如消息队列、事件总线的处理机制。

优点

  • 观察者和被观察者之间是抽象耦合,容易扩展。
  • 方便建立一套触发机制。

缺点

  • 在应用观察者模式时需要考虑一下开发效率和运行效率的问题。程序中包括一个被观察者、多个观察者,开发、调试等内容会比较复杂,而且在 Java 中消息的通知一般是顺序执行的,那么一个观察者卡顿,会影响整体的执行效率,在这种情况下,一般会采用异步方式。

责任链模式

定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,只到有对象处理它为止。

使用场景

多个对象可以处理同一请求,但具体由哪个对象处理则在运行时动态决定。
在请求处理者不明确的情况下向多个对象中的一个提交一个请求。
需要动态指定一组对象处理请求。

角色

  • Handler:抽象处理者角色,声明一个请求处理的方法,并在其中保持一个对下一个处理节点
    Handler对象的引用。
  • ConcreteHandler:具体处理者角色,对请求进行处理,如果不能处理则将该请求转发给下一个
    节点上的处理对象。

简单实现

在这里插入图片描述

  • 在这个抽象的领导类中只做了两件事,一是定 义了两个抽象接口方法来确定一个领导者应有的
    行为和属性,
  • 二是声明了一个处理报账请求的方法来确定当前领导是否有能力处理报账请求,如果
    没有这权限,则将该请求转发给上级领导处理。

接下来则是各个领导类的实现。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
对于责任链中的一一个处理者对象,其只有两个行为,一是处理请求,二是将请求转送给下一个
节点,不允许某个处理者对象在处理了请求后又将请求转送给上一个节点的情况。

对于一条责任链来说,一个请求最终只有两种情况,一是被某个处理对象所处理,另一个是所有对象均未对其处理,对于前一种情况我们称该责任链为纯的责任链,对于后一种情况我们称为不纯的责任链,在实际应用中,我们所见到的责任链模式大多为不纯的责任链。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值