Java设计模式之策略模式与状态模式
一、策略模式定义
定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们之间可以相互替换,策略模式可以在不影响客户端的情况下发生变化。
好了,定义看看就完了,我知道你很烦看定义。
二、策略模式涉及到的三个角色
环境(Context)角色 持有一个Strategy的引用
抽象策略(Strategy)角色 这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
具体策略(ConcreteStrategy)角色 包装了具体的算法或行为。
三、策略模式使用举例
还是赶快看代码吧,知道你看上面定义都烦死了。
我们写一个简单的Demo来对策略模式进行更深的理解,我们模拟游戏中玩家参与一个活动购买金币,普通玩家没有折扣,高级玩家9折优惠,VIP玩家7折优惠。
首先我们定义一个接口,这就是抽象策略角色,如下:
public interface GameStrategy {public void goldCoin();}
很简单,就是一个接口。
接下来我们编写具体策略角色类,从需求就能明白,需要有三个具体策略角色类,也就是三个策略对应不同等级玩家。
普通玩家策略类:
public class normalStrategy implements GameStrategy { @Override public void goldCoin() { // System.out.println("普通玩家没有折扣"); } }
高级玩家策略类:
public class advancedStrategy implements GameStrategy {@Overridepublic void goldCoin() {// TODO Auto-generated method stubSystem.out.println("高级会员9折优惠");} }
VIP玩家策略类:
public class vipStrategy implements GameStrategy { @Override public void goldCoin() { // System.out.println("VIP会员7折优惠"); } }
都很简单,就是简单打印信息。
然后编写环境角色类,如下:
public class Context { //持有一个Strategy的引用 private GameStrategy mGameStrategy; // 构造函数 public Context(GameStrategy strategy) { this.mGameStrategy = strategy; } public void setStrategy(GameStrategy strategy) { this.mGameStrategy = strategy; } public void goldCoin() { this.mGameStrategy.goldCoin(); } }
最后就是调用了,根据不同情况调用不同策略:
public class main { public static void main(String[] args) { //普通玩家策略 Context context = new Context(new normalStrategy()); context.goldCoin(); //高级玩家策略 context.setStrategy(new advancedStrategy()); context.goldCoin(); //高级玩家策略 context.setStrategy(new vipStrategy()); context.goldCoin(); } }
不同情况下我们替换为对应策略就可以了。
四、策略模式优缺点
优点
策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免代码重复。使用策略模式可以避免使用多重条件(if-else)语句。多重条件语句不易维护,它把采取哪一种算法让子类实现
缺点
通过上面Demo我们会发现调用者必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类并且由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观。
好了上面就是策略模式的介绍了,关键是自己慢慢理解。接下来我们了解一下状态模式。
五、状态模式定义
当一个对象在其内部状态改变的时候改变其行为。这个对象看上去就像是改变了它的类一样。又称状态对象模式,状态模式是对象的行为模式。
简单的理解就是一个类其状态改变了,那么其功能也相应的改变了。比如水变为冰,状态改变了,其功能也发生了相应变化。
六、状态模式角色
● Context(环境类):环境类又称为上下文类,它是拥有多种状态的对象。由于环境类的状态存在多样性且在不同状态下对象的行为有所不同,因此将状态独立出去形成单独的状态类。在环境类中维护一个抽象状态类State的实例,这个实例定义当前状态,在具体实现时,它是一个State子类的对象。
● State(抽象状态类):它用于定义一个接口以封装与环境类的一个特定状态相关的行为,在抽象状态类中声明了各种不同状态对应的方法,而在其子类中实现类这些方法,由于不同状态下对象的行为可能不同,因此在不同子类中方法的实现可能存在不同,相同的方法可以写在抽象状态类中。
● ConcreteState(具体状态类):它是抽象状态类的子类,每一个子类实现一个与环境类的一个状态相关的行为,每一个具体状态类对应环境的一个具体状态,不同的具体状态类其行为有所不同。
七、状态模式使用举例
接下来我们编写一个小Demo来进行更深入理解:在办公系统中,一个文件会有不同状态:未处理,正在处理,已经处理。我们就简单模拟一下文件状态的切换。
首先我们看下抽象状态类,很简单就是定义一个接口:
public interface State { void fileState(); }
接下来看下三个具体状态类:
未处理状态类
public class NotDealState implements State{ @Override public void fileState() { // TODO Auto-generated method stub System.out.println("文件未处理状态"); } }
正在处理状态类:
public class DealingState implements State{ @Override public void fileState() { // TODO Auto-generated method stub System.out.println("文件正在处理状态"); } }
已经处理状态类
public class HasDealState implements State{ @Override public void fileState() { // TODO Auto-generated method stub System.out.println("文件已经处理状态"); } }
是不是很简单,同样也只是打印一些简单的信息罢了。
然后看下上下文类:
public class FileContext { //默认情况下未处理状态 private State fileState = new NotDealState(); /** * 文件状态切换为未处理状态 */ public void notDeal(){ this.fileState = new NotDealState(); } /** * 文件状态切换为正在处理状态 */ public void Dealing(){ this.fileState = new DealingState(); } /** * 文件状态切换为已经处理状态 */ public void HasDeal(){ this.fileState = new HasDealState(); } /** * 获取当前文件的状态 */ public void getFileState(){ fileState.fileState(); } }
上下文类主要就是封装当前文件状态并且对外提供状态切换的方法
最后看下怎么使用吧:
public class Client { public static void main(String[] args) { FileContext fileContext = new FileContext(); fileContext.getFileState(); //切换为正在处理状态 fileContext.Dealing(); fileContext.getFileState(); //切换为已经处理状态 fileContext.HasDeal(); fileContext.getFileState(); } }
外部使用调用相应切换状态方法就可以了,很简单,没有什么需要特别说明的。
八、状态模式与策略模式区别以及联系
策略模式与状态模式及其相似,但是二者有其内在的差别,策略模式将具体策略类暴露出去,调用者需要具体明白每个策略的不同之处以便正确使用。而状态模式状态的改变是由其内部条件来改变的,与外界无关,二者在思想上有本质区别。
好了,状态模式与策略模式讲解到此为止,二者区别联系不是几句话就能说清楚,关键是思想上的不同,具体感悟需要在实践中自己慢慢体会。
参考:Java设计模式之策略模式与状态模式
Java设计模式之策略模式与状态模式相关推荐
- Java设计模式之行为型:状态模式
背景: 介绍状态模式前,我们先看这样一个实例:公司力排万难终于获得某个酒店的系统开发项目,并且最终落到了你的头上.下图是他们系统的主要工作: 当第一眼看到这个系统时你就看出这是一个状态图,每个框都代表 ...
- 【每天一个java设计模式(十七)】 - 状态模式
在状态模式中,类的行为是基于它的状态改变的,允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类.这种类型的设计模式属于行为型模式. 在状态模式中,我们创建表示各种状态的对象和一个行为 ...
- 颜值10分姐姐带我玩转java设计模式(内附照片)- 状态模式
先不说话,直接来张姐姐照片,称呼上官姐姐即可,希望上官姐姐能带飞 原创不易,麻烦先三连,再细看,谢谢 示例的源码可以直接通过csdn下载也可以通过git导出:https://github.com/ig ...
- Java设计模式之行为型:解释器模式
一.什么是解释器模式: 解释器模式,就是定义语言的文法,并建立一个解释器来解释该语言中的句子,通过构建解释器,解决某一频繁发生的特定类型问题实例. 这里我们将语言理解成使用规定格式和语 ...
- Java设计模式之行为型:访问者模式
背景: 去医院看病时,医生会给你一个处方单要你去拿药,拿药我们可以分为两步走: (1)去柜台交钱,划价人员会根据处方单上的药进行划价,交钱. (2)去药房拿药,药房工作者同样根据处方单给你相对应的药. ...
- Java设计模式之行为型:备忘录模式
在开发过程中,经常需要保存对象的中间状态,当需要的时候,可以恢复到这个状态.比如,在编程时假如编写失误,例如不小心误删除了几行代码,我们希望返回删除前的状态,便可以使用 Ctrl+Z 来进行返回,这时 ...
- Java设计模式之行为型:命令模式
前言: 在开发中,我们可能需要向某些对象发送一些请求,但我们不知道请求的具体接收者是谁,也不知道被请求的操作是哪个,只知道在系统运行中指定具体的请求接收者即可,打个比方,电视遥控器,我们只需知道按哪个 ...
- Java设计模式之行为型:迭代器模式
一.什么是迭代器模式: 实际开发中,我们针对不同的需求,可能需要以不同的方式来遍历整个整合对象,但我们不希望在集合容器的抽象接口层中充斥着各种不同的遍历操作,这时候我们就需要一种能完成下面功能的迭代器 ...
- Java设计模式之行为型:模板方法模式
一.什么是模板方法模式: 模板方法是基于继承实现的,在抽象父类中声明一个模板方法,并在模板方法中定义算法的执行步骤(即算法骨架).在模板方法模式中,可以将子类共性的部分放在父类中实现,而特性的部分延迟 ...
- Java设计模式之结构型:组合模式
前言: 我们对于上面两幅图片肯定非常熟悉,这两幅图片我们都可以看做是一个文件结构,对于这样的结构我们称之为树形结构.在数据结构中我们知道可以通过调用某个方法来遍历整个树,当我们找到某个叶子节点后,就可 ...
最新文章
- Codeforces 446C —— DZY Loves Fibonacci Numbers(线段树)
- 二值mask图像 + RGB原图 生成可视化分割结果; 从二值mask获取分割轮廓点
- SQL中读取Excel 以及 bpc语言
- html对图片轮播脚本怎么调用,【jquery前端开发】可调整的幻灯片(图片轮播)
- 【Computer Organization笔记07】实验课:可编程逻辑器件介绍,硬件编程方法与原则,硬件编程流程
- Windows 10专业版下如何启用语音识别功能
- Pannellum:实例之自动加载全景图
- 亮风台AR眼镜震撼发布 HiAR 产品全面升级
- java郝斌_Java入门学习笔记-郝斌
- Ubuntu20.04安装搜狗输入法指南
- HTML+css实现元素居中对齐的方法
- XX和OO(南阳oj1159)
- 如何申请自己的免费企业邮箱
- 74HC595芯片工作原理细致分析(以及级联拓展应用),以及芯片控制继电器原理 / 代码
- python 读写文件 把爬取的图片信息写入文件
- 2016php开发 饱和了吗,2016PHP程序员待遇和就业前景调查
- 古典微分几何 近代微分几何资料
- 回顾总结-----第九届中国云计算大会,量子计算机为最大亮点
- [AH2017/HNOI2017]抛硬币
- 在地址栏上输入一个url,到这个页面呈现出来,中间会发生什么?