委派模式和策略模式

一、委派模式

委派模式(Delegate Pattern):指负责任务的调度和分配任务,跟代理模式很像,可以看做是一种特殊情况下的静态代理的全权代理,但是代理模式注重过程,而委派模式注重结果。(属于行为型模式,但它不属于GOF的23种设计模式之一。类名以Delegate和Dispatcher结尾的一般都是委派模式)

委派模式在Spring中应用非常多,大家常用的DispatcherServlet其实就用到了委派模式。现实生活中也常有委派的场景发生,例如:老板(Boss)给项目经理(Leader)下达任务,项目经理会根据实际情况给每个员工派发工作任务,待员工把工作任务完成之后,再由项目经理汇报工作进度和结果给老板,业务场景如下图:

例子1:用代码来模拟一下这个业务场景,定义一个IEmployee员工接口:

定义一个员工EmployeeA类:

定义一个员工EmployeeB类:

定义一个项目经理Leader类:

定义一个Boss类下达命令:

测试代码:

运行结果:

类结构图:

通过上面的代码,生动地还原了项目经理分配工作的业务场景,也是委派模式的生动体现。

委派模式在源码中的体现

例子2:还原SpirngMVC的DispatcherServlet是如何实现委派模式的。定义一个MemberController类 :

定义一个OrderController类:

定义一个DispatcherServlet类:

配置web.xml文件:

二、策略模式

1、策略模式(Strategy pattern):指定义了算法家族、分别封装起来,让它们之间可以相互替换,此模式让算法的变化不会影响到使用算法的用户。(属于行为型模式)

2、适用场景

  • 假如系统中有很多类,而他们的区别仅仅在于他们的行为不同
  • 一个系统需要动态地在几种算法中选择一种

3、优点

  • 策略模式符合开闭原则
  • 避免使用多重条件转移语句,如if...else...和switch语句
  • 使用策略模式可以提高算法的保密性和安全性

4、缺点

  • 客户端必须知道所有的策略,并且自行决定使用哪一个策略类
  • 代码中产生非常多策略类,增加维护难度

例子1:有一个课程优惠活动,优惠策略会有多种,如领优惠券抵扣、返现促销等。下面用代码来模拟:

定义一个促销策略PromotionStragegy接口:

定义一个优惠券折扣策略CouponStragegy类:

定义一个返现促销策略CashbackStrategy类:

定义一个无优惠EmptyStrategy类:

定义一个促销活动方案PromotionActivity类:

编写客户端测试类:

此时大家会发现,如果把上面这段测试代码放到实际的业务场景其实并不实用。因为我们做活动时往往是根据不同的需求对促销策略进行动态选择的,并不会一次性执行多种优惠。所以,我们的代码通常会这样写:

这样改造之后,满足了业务需求,客户可根据自己的需求选择不同的优惠策略了。但是,经过一段时间的业务积累,我们的促销活动会越来越多。于是,我们的程序猿小哥哥就忙不赢了,每次上活动之前都要通宵改代码,而且要做重复测试,判断逻辑可能也变得越来越复杂。这时候,我们可以结合之前学过的单例模式和工厂模式。定义一个策略工厂PromotionStrategyFactory类:

这时候客户端代码就应该这样写了:

类结构图:

代码优化之后,程序猿小哥哥维护工作就轻松多了,每次上新活动,不影响原来的代码逻辑。

例子2:一个常见的应用场景就是大家在下单支付时会提示选择支付方式,如果用户未选,系统也会使用默认推荐的支付方式进行结算。

定义一个支付渠道Payment抽象类,声明支付规范和支付逻辑:

定义具体的支付方式,支付宝AliPay类:

微信支付WechatPay类:

定义一个支付状态的包装类PayState:

定义一个支付策略管理PayStrategy类:

定义一个Order订单类:

测试代码:

运行结果:

三、委派模式与策略模式综合应用

回顾一下DispatcherServlet的委派逻辑,代码如下:

这样的代码扩展性不太优雅,也不现实,因为我们实际项目中一定不止这几个Controller,往往是成千上万个Controller,显然我们不能写成千上万个if...else...。那么我们可以结合策略模式改造优化一下:

定义一个Handler类:

改造DispatcherServlet类:

上面的代码结合了委派、策略、工厂、单例模式。

原文地址:https://www.cnblogs.com/ZekiChen/p/12527924.html

时间: 2024-10-16 02:47:15

委派模式和策略模式的相关文章

设计模式之桥梁模式和策略模式的区别

桥接(Bridge)模式是结构型模式的一种,而策略(strategy)模式则属于行为模式.以下是它们的UML结构图. 桥梁模式: 策略模式: 在桥接模式中,Abstraction通过聚合的方式引用Implementor. 举一个例子: 策略模式:我要画圆,要实心圆,我可以用solidPen来配置,画虚线圆可以用dashedPen来配置.这是strategy模式. 桥接模式:同样是画圆,我是在windows下来画实心圆,就用windowPen+solidPen来配置,在unix下画实心圆就用uni

【设计模式】 模式PK:命令模式VS策略模式

1.概述 命令模式和策略模式的类图确实很相似,只是命令模式多了一个接收者(Receiver)角色.它们虽然同为行为类模式,但是两者的区别还是很明显的.策略模式的意图是封装算法,它认为"算法"已经是一个完整的.不可拆分的原子业务(注意这里是原子业务,而不是原子对象),即其意图是让这些算法独立,并且可以相互替换,让行为的变化独立于拥有行为的客户:而命令模式则是对动作的解耦,把一个动作的执行分为执行对象(接收者角色).执行行为(命令角色),让两者相互独立而不相互影响. 我们从一个相同的业务需

【设计模式】简单工厂模式与策略模式

[前言]今天再次把<大话设计模式>一书拿出来翻了一下,对于前面一节初探中讲诉的简单工厂模式和策略模式,有了更好的理解.按照习惯,还是继续梳理梳理. [简单工厂模式]:封装(数据+算法) 简单工厂模式的特点: 每一个子类最好能做到职责单一,将每一个需要涉及的数据和算法,封装成一个独立的类. 工厂模式中的工厂类其实起到了一个调度者的角色: 2.1 工厂类可以达到将实现具体逻辑的子类隐藏的效果,只需要将自己暴露调用实例化的接口,根据工厂类提供的对外方法,在内部实现逻辑判断,并最后实例化具体的子类对象

工厂模式与策略模式之区别

设计模式有很多种,其中功能相似的很多,但是为什么还要分这么多种名字,查阅资料,我觉得下面的解释最为合理:用途不一样,名字就有区别,一把斧头用来砍人就叫凶器,用来砍柴就叫伐木斧,用来劈门就叫消防斧,这些模式的名字都是根据具体使用时的场景,联系了现实里某样东西或某种习惯而取得,所以很相似的模式行为有不同叫法. 今天我们就来研究一些工厂模式与策略模式的一些区别: 工厂模式是创建型模式,适应对象的变化. 策略模式是行为性模式,适应行为的变化 工厂模式封装对象,实例化对象后调用的时候要知道具体的方法,策略

跟我学设计模式视频教程——命令模式vs策略模式,唠嗑

课程视频 命令模式vs策略模式 唠嗑 课程笔记 课程笔记 课程代码 课程代码 新课程火热报名中 课程介绍 跟我学设计模式视频教程--命令模式vs策略模式,唠嗑,布布扣,bubuko.com

从桥接模式与策略模式谈起(转载)

原文地址:http://www.blogjava.net/wangle/archive/2007/04/25/113545.html 从桥接模式与策略模式谈起 桥接(Bridge)模式是结构型模式的一种,而策略(strategy)模式则属于行为模式.以下是它们的UML结构图. 在桥接模式中,Abstraction通过聚合的方式引用Implementor. 在策略模式中,Context也使用聚合的方式引用Startegy抽象接口. 从他们的结构图可知,在这两种模式中,都存在一个对象使用聚合的方式引

浅谈简单工厂模式和策略模式

1.简单工厂模式如图 代码: 缺点:简单工厂模式需要客户端认识两个类,Cash和CashFactory 优点:子类的实例化被工厂封装了起来,客户端看不到 2.策略模式如图 代码: public class Context{ Strategy strategy; public Context(Strategy strategy){ this.strategy = strategy; } public double getResult(double money){ return strategy.a

设计模式之_简单工厂模式、工厂方法模式、抽象工厂模式 、策略模式、策略与工厂的区别(转)

一.前言 话说十年前,有一个爆发户,他家有三辆汽车(Benz(奔驰).Bmw(宝马).Audi(奥迪)),还雇了司机为他开车.不过,爆发户坐车时总是这样:上Benz车后跟司机说“开奔驰车!”,坐上Bmw后他说“开宝马车!”,坐上 Audi后他说“开奥迪车!”.你一定说:这人有病!直接说开车不就行了?!而当把这个爆发户的行为放到我们程序语言中来,我们发现C语言一直是通过这种方式来坐车的 幸运的是这种有病的现象在OO语言中可以避免了.下面以Java语言为基础来引入我们本文的主题:工厂模式! 二.简介

简单工厂模式和策略模式的区别

直接上代码: 简单工厂模式: ------------------------------一个抽象类   -------------------------- abstract class AbsClass { //抽象方法:提供一些列的算法操作 public abstract void acceptCash(string org); } ------------------------------2个实现类   -------------------------- //继承自抽象类 class