【设计模式系列】行为型之策略模式
定义
首先介绍一下众多博客文章中提到的策略模式的概念,针对于文章结构构成,请允许小编在此处再细说一下。
策略模式:百度百科中引述为:指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。
1.策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理。
2.策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是:“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。
【此处的算法,大家可以理解为解决业务需求的方法。】
对于这些概念大家理解起来或许有些抽象,耐心往下读,相信大家肯定会有所收获。
组成
- 环境(Context)角色:持有一个Strategy的引用。
- 抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
- 具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。
理解
对于设计模式中的策略模式,大家众多的解释可能侧重与解决if…else,switch-cas这种条件语句的优化,小编简单谈一下我在项目中实际应用和理解吧;对于策略模式按照上面给予的定义理解,是将多个业务节点具备的共同算法再次顶层抽象为接口,处理不同业务需求时,则产生的行为不同,即具体行为由其实现类解决;注重词:相同算法,,顶层抽出。
再简单举例说明一下,比如工作的OA系统中,流程节点具体相同的功能:提交,回退,撤回等等(抽象策略类);但是每个流程节点所实现的功能不同(具体策略类);
实现
小编以我们日常生活中最常见的支付方式为例,解答策略模式的应用。
无论使用xiaomi,huawei,apple均存在相同的行为(算法),例如:支付方式不同,客户端享受的优惠力度不等。故我们将支付作为共同的接口抽象出来。
UML
抽象策略类
将支付作为共同算法,顶层抽象。
/*** @author wx* @date 2021/03/05 1:50 下午*/
public interface PayStrategy {void pay(double money);
}
具体策略类
MiPAY
/*** @author wx* @date 2021/03/05 1:51 下午*/
public class MiPayStrategy implements PayStrategy{@Overridepublic void pay(double money) {double payMoney = money * 0.87;double discountMoney = money - payMoney;System.out.println("使用Mi pay成功支付" + payMoney + "元,优惠" + discountMoney + "元");}
}
HuaWeiPAY
/*** @author wx* @date 2021/03/05 1:50 下午*/
public class HuaWeiPayStrategy implements PayStrategy{@Overridepublic void pay(double money) {double payMoney = money * 0.85;double discountMoney = money - payMoney;System.out.println("使用HuaWei pay成功支付" + payMoney + "元,优惠" + discountMoney + "元");}
}
ApplePAY
/*** @author wx* @date 2021/03/05 1:52 下午*/
public class ApplePayStrategy implements PayStrategy{@Overridepublic void pay(double money) {double payMoney = money * 0.82;double discountMoney = money - payMoney;System.out.println("使用Apple pay成功支付" + payMoney + "元,优惠" + discountMoney + "元");}
}
环境类
供客户端调用,并选择具体策略
/*** @author wx* @date 2021/03/05 1:53 下午*/
public class PayContext {//依赖策略接口属性private PayStrategy payStrategy;public void setPayStrategy(PayStrategy payStrategy) {this.payStrategy = payStrategy;}/*** 提供外部访问方法* @param money*/public void payMoney(double money) {payStrategy.pay(money);}
}
客户端
客户端则已知选择的支付方式,可以服务端依据不同支付策略选择折扣。
/*** @author wx* @date 2021/03/05 1:59 下午*/
public class PayClient {public static void main(String[] args) {//创建支付上下文PayContext payContext = new PayContext();//创建支付策略,客户端已知存在具体策略PayStrategy miPayStrategy = new MiPayStrategy();payContext.setPayStrategy(miPayStrategy);payContext.payMoney(100);System.out.println("-------改变支付策略--------");PayStrategy applePayStrategy = new ApplePayStrategy();payContext.setPayStrategy(applePayStrategy);payContext.payMoney(100);}
}
执行结果:
理解了策略模式的使用,下面简单谈谈该模式的优点和缺点:
- 优点:
1.毫不疑问复合设计模式中的开闭原则,新增支付方式则扩展策略类即可,无须改动其他策略类的实现;
2.消除if-else类似的判断语句,整合代码结构,符合代码整洁之道; - 缺点:
1.从类的数量上而言,若策略选择很多,则造成策略类数量增加;
2.所有策略类都需要对外暴露。即客户端必须知道所有的策略类,并自行决定使用哪一个策略类,故不得不向客户暴露具体的实现。
类比其他模式
策略模式和状态模式:
一、执行方式:
策略模式:客户端策略条件选择只执行一次;
状态模式:随着实例参数(对象实例的状态)的改变不停地更改执行模式。
简言之,策略模式只是在对象初始化的时候更改执行模式,而状态模式是根据对象实例的周期时间而动态地改变对象实例的执行模式。
二、环境类
策略模式:环境类自己选择一个具体策略类,具体策略类无须关心环境类 ;
状态模式:环境类由于外在因素需要放进一个具体状态中,以便通过其方法实现状态的切换 ,因此环境类和状态类之间存在一种双向的关联关系。
简言之,使用策略模式时客户端需要知道所选的具体策略是哪一个;
而使用状态模式时, 客户端无须关心具体状态 ,环境类的状态会根据用户的操作自动转换。
【设计模式系列】行为型之策略模式相关推荐
- Java设计模式之行为型:策略模式
一.背景: 在开发中经常遇到这种情况,实现某个功能有多种算法策略,我们可以根据不同环境或者条件选择不同的算法策略来完成该功能,比如查找.排序等,一种常用方式是硬编码在一个类中,如需要提供多种查找算法, ...
- 【设计模式】行为型01策略模式(strategy patten)
学设计模式一段时间了,有些懂了,有些半知半解,通过写笔记博客的方式总结一下: 关于策略模式,我的个人理解就是将一些经常变动的算法独立抽取出来,可以是一个方法,也可以是一个策略类,这样,如果有需求变更, ...
- Java设计模式之行为型:解释器模式
一.什么是解释器模式: 解释器模式,就是定义语言的文法,并建立一个解释器来解释该语言中的句子,通过构建解释器,解决某一频繁发生的特定类型问题实例. 这里我们将语言理解成使用规定格式和语 ...
- Java设计模式之行为型:访问者模式
背景: 去医院看病时,医生会给你一个处方单要你去拿药,拿药我们可以分为两步走: (1)去柜台交钱,划价人员会根据处方单上的药进行划价,交钱. (2)去药房拿药,药房工作者同样根据处方单给你相对应的药. ...
- Java设计模式之行为型:状态模式
背景: 介绍状态模式前,我们先看这样一个实例:公司力排万难终于获得某个酒店的系统开发项目,并且最终落到了你的头上.下图是他们系统的主要工作: 当第一眼看到这个系统时你就看出这是一个状态图,每个框都代表 ...
- Java设计模式之行为型:备忘录模式
在开发过程中,经常需要保存对象的中间状态,当需要的时候,可以恢复到这个状态.比如,在编程时假如编写失误,例如不小心误删除了几行代码,我们希望返回删除前的状态,便可以使用 Ctrl+Z 来进行返回,这时 ...
- Java设计模式之行为型:命令模式
前言: 在开发中,我们可能需要向某些对象发送一些请求,但我们不知道请求的具体接收者是谁,也不知道被请求的操作是哪个,只知道在系统运行中指定具体的请求接收者即可,打个比方,电视遥控器,我们只需知道按哪个 ...
- Java设计模式之行为型:迭代器模式
一.什么是迭代器模式: 实际开发中,我们针对不同的需求,可能需要以不同的方式来遍历整个整合对象,但我们不希望在集合容器的抽象接口层中充斥着各种不同的遍历操作,这时候我们就需要一种能完成下面功能的迭代器 ...
- Java设计模式之行为型:模板方法模式
一.什么是模板方法模式: 模板方法是基于继承实现的,在抽象父类中声明一个模板方法,并在模板方法中定义算法的执行步骤(即算法骨架).在模板方法模式中,可以将子类共性的部分放在父类中实现,而特性的部分延迟 ...
- Java设计模式之创建型:原型模式
一.什么是原型模式: 原型模式主要用于对象的创建,使用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象.UML类图如下: 原型模式的核心是就是原型类 Prototype,Prototype ...
最新文章
- shell中sed命令的用法
- JavaScript库开发者们的规则
- mac 多java环境变量配置_java_Mac安装多个JDK版本并设置环境变量
- 编写python程序、创建名为class的数据库_Python中的元类(metaclass)以及元类实现单例模式...
- 陶哲轩的10岁与30岁
- 【flume】flume的安装配置理解
- 清空文件夹,或删除文件夹
- MongDB之shard_主从,副本集,分片的理解
- 3文字怎么断行_Word闹鬼,行首出现删不掉的空格怎么办?
- Expression Blend实例中文教程(12) - 样式和模板快速入门Style,Template
- 8数据提供什么掩膜产品_英特尔推出多款数据中心产品:继续提供差异化选项...
- ARM体系结构与编程
- Common Digester学习
- 五险一金及个税计算器
- 中文Win10 任务栏右键菜单是英文
- css font size 单位,css中font-size的单位总结:px、em、pt
- 服务器CPU占用过高如何解决
- 电脑出现Hold Escape key to prevent StartlsBack from loading,导致电脑闪屏。
- qq屏幕识图如何一次复制所有文字
- linux ATT汇编 输出hello world
热门文章
- Silverlight中使用MVVM(2)
- discuz! 7.2 manyou插件暴路径Get Webshell 0day
- Spring Mvc 整合 Mybatis
- 求出千位数上的数加百位数上的数等于十位数上的数加个位数上的数的个数cnt,再把所有满足条件的四位数依次存入数组b中,然后对数组b中的四位数按从大到小的顺序进行排序。
- spark RadixSort基数排序源码实现
- java中类的命名规则_java类方法属性的命名规范介绍
- mysql数据存储过程详解_mysql数据存储过程参数实例详解
- git 忽略文件提交的几种姿势
- golang 监听服务的信号,实现平滑启动,linux信号说明
- ios端input 光标问题