状态设计模式示例

本文是我们名为“ Java设计模式 ”的学院课程的一部分。

在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因,并了解何时以及如何应用模式中的每一个。 在这里查看 !

目录

1.简介 2.什么是状态设计模式 3.实施状态设计模式 4.何时使用状态设计模式 5. Java中的状态设计模式 6.下载源代码

1.简介

为了说明“状态设计模式”的使用,让我们帮助一家正在寻求制造烹饪机器人的公司。 该公司想要一个简单的机器人,它可以简单地走路和煮饭。 用户可以通过遥控器使用一组命令来操作机器人。 当前,机器人可以做三件事,它可以走路,做饭或关闭。

该公司已设置协议来定义机器人的功能。 如果机器人处于“开启”状态,则可以命令它行走。 如果要求烹饪,状态将变为“烹饪”,或者如果设置为“关闭”,则将其关闭。

同样,处于“烹饪”状态时,它可以走路或做饭,但不能关闭。 最后,当处于“关闭”状态时,当用户命令它走路但不能在关闭状态下烹饪时,它将自动上走。

这可能看起来像是一个简单的实现:机器人类具有一组方法,如走动,烹饪,关闭以及状态(如打开,烹饪和关闭)。 我们可以使用if-else分支或使用switch来实现公司设置的协议。 但是过多的if-else或switch语句将造成维护的噩梦,因为将来的复杂性可能会增加。

您可能认为我们可以使用if-else语句来实现此目的,但是随着更改的来临,代码将变得更加复杂。 需求清楚地表明,对象的行为确实基于该对象的状态。 我们可以使用状态设计模式,该模式将对象的状态封装到另一个单独的类中,并使上下文类独立于任何状态更改。

首先让我们了解状态设计模式,然后将其实现以解决上述问题。

2.什么是状态设计模式

状态设计模式允许对象在其内部状态更改时更改其行为。 该对象似乎将更改其类。

可以将对象的状态定义为在任何给定时间点的确切条件,具体取决于其属性或属性的值。 由类实现的方法集构成其实例的行为。 只要它的属性值发生变化,我们就说对象的状态已发生变化。

状态模式可用于为类设计有效的结构,该类的典型实例可以存在于许多不同的状态中,并根据其所处的状态而表现出不同的行为。换句话说,对于此类对象,类,其某些或全部行为完全受其当前状态影响。 在状态设计模式术语中,此类称为Context类。 当内部状态发生变化时, Context对象可以更改其行为,也称为有状态对象。

状态模式建议将特定于状态的行为从Context类中移到一组单独的类中,这些类称为State类。 Context对象可以存在的许多不同状态中的每一个都可以映射到单独的State类中。 State类的实现包含特定于给定状态的上下文行为,而不是上下文本身的整体行为。 从某种意义上说,上下文充当状态对象集的客户端,因为它利用不同的状态对象向无缝使用上下文的应用程序对象提供必要的特定于状态的行为。

通过将特定于状态的行为封装在单独的类中,上下文实现变得更易于阅读:无需太多条件语句(例如if-else或switch-case构造)。 首次创建Context对象时,它将使用其初始State对象进行初始化。 该State对象成为上下文的当前State对象。 通过用新的State对象替换当前的State对象,上下文将转换为新的状态。

使用上下文的客户端应用程序不负责为上下文指定当前的State对象,而是代表特定状态的每个State类均应提供将上下文转换为其他状态的必要实现。 当应用程序对象调用Context方法(行为)时,它将方法调用转发到其当前的State对象。

图1-类图

图1 –类图

语境

  • 定义客户感兴趣的界面。
  • 维护定义当前状态的ConcreteState子类的实例。

  • 定义用于封装与Context的特定状态关联的行为的接口。

ConcreteState子类

  • 每个子类都实现与Context状态关联的行为。

3.实施状态设计模式

以下是RoboticState接口,其中包含机器人的行为。

package com.javacodegeeks.patterns.statepattern;public interface RoboticState {public void walk();public void cook();public void off();}

Robot类是实现RoboticState接口的具体类。 该类包含机器人可能处于的所有可能状态的集合。

package com.javacodegeeks.patterns.statepattern;public class Robot implements RoboticState{private RoboticState roboticOn;private RoboticState roboticCook;private RoboticState roboticOff;private RoboticState state;public Robot(){this.roboticOn = new RoboticOn(this);this.roboticCook = new RoboticCook(this);this.roboticOff = new RoboticOff(this);this.state = roboticOn;}public void setRoboticState(RoboticState state){this.state = state;}@Overridepublic void walk() {state.walk();}@Overridepublic void cook() {state.cook();}@Overridepublic void off() {state.off();}public RoboticState getRoboticOn() {return roboticOn;}public void setRoboticOn(RoboticState roboticOn) {this.roboticOn = roboticOn;}public RoboticState getRoboticCook() {return roboticCook;}public void setRoboticCook(RoboticState roboticCook) {this.roboticCook = roboticCook;}public RoboticState getRoboticOff() {return roboticOff;}public void setRoboticOff(RoboticState roboticOff) {this.roboticOff = roboticOff;}public RoboticState getState() {return state;}public void setState(RoboticState state) {this.state = state;}}

该类初始化所有状态并将当前状态设置为on。

现在,我们将看到机器人的所有具体状态。 机器人将随时处于任何一种状态。

package com.javacodegeeks.patterns.statepattern;public class RoboticOn implements RoboticState{private final Robot robot;public RoboticOn(Robot robot){this.robot = robot;}@Overridepublic void walk() {System.out.println("Walking...");}@Overridepublic void cook() {System.out.println("Cooking...");robot.setRoboticState(robot.getRoboticCook());}@Overridepublic void off() {robot.setState(robot.getRoboticOff());System.out.println("Robot is switched off");}}
package com.javacodegeeks.patterns.statepattern;public class RoboticCook implements RoboticState{private final Robot robot;public RoboticCook(Robot robot){this.robot = robot;}@Overridepublic void walk() {System.out.println("Walking...");robot.setRoboticState(robot.getRoboticOn());}@Overridepublic void cook() {System.out.println("Cooking...");}@Overridepublic void off() {System.out.println("Cannot switched off while cooking...");}
}
package com.javacodegeeks.patterns.statepattern;public class RoboticOff implements RoboticState{private final Robot robot;public RoboticOff(Robot robot){this.robot = robot;}@Overridepublic void walk() {System.out.println("Walking...");robot.setRoboticState(robot.getRoboticOn());}@Overridepublic void cook() {System.out.println("Cannot cook at Off state.");}@Overridepublic void off() {System.out.println("Already switched off...");}
}

现在,让我们测试代码。

package com.javacodegeeks.patterns.statepattern;public class TestStatePattern {public static void main(String[] args) {Robot robot = new Robot();robot.walk();robot.cook();robot.walk();robot.off();robot.walk();robot.off();robot.cook();}}

上面的代码将导致以下输出:

Walking...
Cooking...
Walking...
Robot is switched off
Walking...
Robot is switched off
Cannot cook at Off state.

在上面的示例中,我们已经看到通过将对象的状态封装到不同的类中可以使代码易于管理和灵活。

状态的任何更改只会影响该特定的类,我们可以在不更改现有代码的情况下包括一个新状态。 例如,我们包含一个备用状态。 散步或做饭后,机器人进入待机模式以节省电量,然后我们再次步行,做饭或从待机模式下关闭。

为了实现所有这些,我们需要引入一个新的状态类,并将该状态包括在Robot类中。 以下是更改。

package com.javacodegeeks.patterns.statepattern;public class Robot implements RoboticState{private RoboticState roboticOn;private RoboticState roboticCook;private RoboticState roboticOff;private RoboticState roboticStandby;private RoboticState state;public Robot(){this.roboticOn = new RoboticOn(this);this.roboticCook = new RoboticCook(this);this.roboticOff = new RoboticOff(this);this.roboticStandby = new RoboticStandby(this);this.state = roboticOn;}public void setRoboticState(RoboticState state){this.state = state;}@Overridepublic void walk() {state.walk();setState(getRoboticStandby());}@Overridepublic void cook() {state.cook();setState(getRoboticStandby());}@Overridepublic void off() {state.off();}public RoboticState getRoboticOn() {return roboticOn;}public void setRoboticOn(RoboticState roboticOn) {this.roboticOn = roboticOn;}public RoboticState getRoboticCook() {return roboticCook;}public void setRoboticCook(RoboticState roboticCook) {this.roboticCook = roboticCook;}public RoboticState getRoboticOff() {return roboticOff;}public void setRoboticOff(RoboticState roboticOff) {this.roboticOff = roboticOff;}public RoboticState getState() {return state;}public void setState(RoboticState state) {this.state = state;}public RoboticState getRoboticStandby() {return roboticStandby;}public void setRoboticStandby(RoboticState roboticStandby) {this.roboticStandby = roboticStandby;}}
package com.javacodegeeks.patterns.statepattern;public class RoboticStandby implements RoboticState{private final Robot robot;public RoboticStandby(Robot robot){this.robot = robot;}@Overridepublic void walk() {System.out.println("In standby state...");robot.setState(robot.getRoboticOn());System.out.println("Walking...");}@Overridepublic void cook() {System.out.println("In standby state...");robot.setRoboticState(robot.getRoboticCook());System.out.println("Cooking...");}@Overridepublic void off() {System.out.println("In standby state...");robot.setState(robot.getRoboticOff());System.out.println("Robot is switched off");}}

现在,以上代码更改将导致以下输出:

Walking...
In standby state...
Cooking...
In standby state...
Walking...
In standby state...
Robot is switched off
Walking...
In standby state...
Robot is switched off
Cannot cook at Off state.

4.何时使用状态设计模式

在以下两种情况下,请使用State模式:

  • 对象的行为取决于其状态,并且它必须在运行时根据该状态更改其行为。
  • 操作具有取决于对象状态的大型,多部分条件语句。 此状态通常由一个或多个枚举常量表示。 通常,几个操作将包含此相同的条件结构。 State模式将条件的每个分支放在单独的类中。 这样一来,您就可以将对象的状态视为独立于其他对象而独立变化的对象。

5. Java中的状态设计模式

  • javax.faces.lifecycle.LifeCycle#execute()

6.下载源代码

这是关于状态设计模式的课程。 您可以在此处下载源代码: StatePattern-Project

翻译自: https://www.javacodegeeks.com/2015/09/state-design-pattern.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/356818.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python基础——错误处理

python基础——错误处理 在程序运行的过程中,如果发生了错误,可以事先约定返回一个错误代码,这样,就可以知道是否有错,以及出错的原因。在操作系统提供的调用中,返回错误码非常常见。比如打开文件的函数ope…

Js操作Select大全(取值、设置选中等等)

jquery操作select(取值&#xff0c;设置选中&#xff09; 每一次操作select的时候&#xff0c;总是要出来翻一下资料&#xff0c;不如自己总结一下&#xff0c;以后就翻这里了。 比如<select class"selector"></select> 1、设置value为pxx的项选中 $(&qu…

java获取数组的最小值_Java 数组获取最大和最小值的实例实现

以下实例演示了如何通过 Collections 类的 Collections.max() 和 Collections.min() 方法来查找数组中的最大和最小值&#xff1a;Main.java 文件&#xff1a;import java.util.Arrays;import java.util.Collections;public class Main {public static void main(String[] args…

Spring_事务(2)

转载于:https://www.cnblogs.com/yang-hao/p/5830952.html

heroku_本月风味– Neo4j和Heroku

herokuNeo4j今年早些时候发起了一项挑战&#xff0c;即“ 种子播云 ”&#xff0c;以使人们使用Neo4j附加组件在Heroku上创建模板或演示应用程序。 经过许多内部辩论之后&#xff0c;我决定进入&#xff0c;但由于缺乏想法而陷入绝望。 当我没有做任何特别的事情时&#xff0c;…

java object对象的方法_Java常见对象Object类中的个别方法

Java常见对象Object类public int hashCode() &#xff1a; 返回该对象的哈希码值。注意&#xff1a;哈希值是根据哈希算法计算出来的一个值&#xff0c;这个值和地址值有关&#xff0c;但是不是实际地址值。你可以理解成地址值。packagecommon_object;public class Demo extend…

很认真地聊一聊程序员的自我修养

最近看了《浅谈程序员的英语学习》&#xff0c;对于文章中的观点我非常认同&#xff0c;英语是非常重要的&#xff0c;但文章站的高度还是太高&#xff0c;具体表述的学习方法我不是很认同&#xff0c;也认为不太实际&#xff0c;恰好之前有一篇一直没有发表的文章想重新发布&a…

Java设计模式教程

课程大纲 架构和计算机科学中的设计模式是记录特定专业领域中设计问题的解决方案的正式方法。 这个想法是由建筑师Christopher Alexander在建筑领域引入的&#xff0c;并已被改编为其他各种学科&#xff0c;包括计算机科学。 设计模式是在软件设计中给定上下文中对常见问题的通…

java字符串学习_java之字符串学习记录

java之字符串学习记录public class StringDemo {public static void main(String[] args) {//静态初始化字符串String s1 "hello china!";String s3 "Hello China!";System.out.println(s1);//动态初始化字符串String s2 new String("hello china!…

IMPDP导入实例(oracle)

【IMPDP导入实例】&#xff1a; su - oracle sqlplus /nolog conn /as sysdba select * from dba_directories; 开始 通过Xshell连接linux服务器后&#xff1a; Connecting to 10.149.56.40:22... [rootoracle ~]# su - oracle [oracleoracle ~]$ sqlplus /nolog SQL> conn …

java中解密技术是什么_详解Java 加密解密技术的分类和归纳

这篇文章主要介绍了Java加密解密基础分类方法汇总的相关资料&#xff0c;需要的朋友可以参考下Java 加密解密基础&#xff1a;密码学是研究编制密码和破译密码的技术科学。研究密码变化的客观规律&#xff0c;应用于编制密码以保守通信秘密的&#xff0c;称为编码学&#xff1b…

三级菜单的三个版本

1.这是我们通过一般方式进行的&#xff0c;就是按照正常的思路来写的&#xff0c;一步一步走 1 #_author:sangshijia2 #date:2016/8/243 menu_map{4 "河南":{5 "郑州":["新密","登封","中牟"],6 "…

java实现细胞自动机_Java自动机实现

java实现细胞自动机这篇文章将解决在Java中实现有限状态机的问题。 如果您不知道什么是FSM或在什么地方可以使用FSM&#xff0c;您可能会热衷于阅读本 &#xff0c; 本和本 。 如果您发现自己在设计上使用FSM的情况&#xff0c;则可能已经开始为实现相同接口的每个状态编写类。…

代理设计模式示例

本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入研究大量的设计模式&#xff0c;并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因&#xff0c;并了解何时以及如何应用模式中的每一个。 在这里查看 &#xff01; 目录 …

调研《构建之法》指导下的历届作品

项目名称&#xff1a;未视APP学校&#xff1a;吉首大学团队&#xff1a;北京必趣科技有限公司 简介&#xff1a;发现未知的视界http://plus.jlu.edu.cn/item.php?id377 延续电影瞬间的感动&#xff0c;发现视界未知的温暖 理由:无优势,很多劣势,可是延续电影瞬间的感动&#x…

java图形旋转动画_Java动画:旋转图像

我将假设您了解如何旋转图像一次.如果你不这样做,你可以通过快速谷歌搜索找到它.您需要的是一个为您旋转它的后台进程.它的工作原理如下&#xff1a;/*** Warning - this class is UNSYNCHRONIZED!*/public class RotatableImage {Image image;float currentDegrees;public Rot…

java golang速度_golang思考之运行速度

有些资料显示golang的运行速度很慢&#xff0c;比Java慢&#xff0c;有时比Python慢。学习吧测试发现golang的运行速度和Java差不多。首先&#xff0c;使用各种语言编写同一个CPU密集的程序sum。C(或C)#include #include #include int main(void){int iN;int64_t jN;scanf(&quo…

java 中的正则表达式_Java中的正则表达式–软介绍

java 中的正则表达式正则表达式是一种可以应用于文本&#xff08;Java中的String&#xff09;的模式。 Java提供了java.util.regex包&#xff0c;用于与正则表达式进行模式匹配。 Java正则表达式与Perl编程语言非常相似&#xff0c;并且非常易于学习。 正则表达式匹配文本&…

HTML5移动端触摸事件

工作了近一个月了 因为公司是主要偏向于移动端&#xff0c;开始不懂移动端事件 一直用的click click在安卓端没有什么问题 但在IOS端就有问题了点击之后会延迟半秒 多亏旁边大神指点 原来 iOS上的Safari也支持click 和mouseover等传统的交互事件&#xff0c;只是不推荐在iOS…

用java写的教职工信息管理系统_基于Java的教师信息管理系统的设计与实现论文.doc...

基于Java的教师信息管理系统的设计与实现论文职场大变样社区()&#xff1a;下载毕业设计成品全套资料&#xff0c;全部50元以下毕业设计(论文)任务书第1页毕业设计(论文)题目&#xff1a;基于java的教师信息管理系统的设计与实现毕业设计(论文)要求及原始数据(资料)&#xff1a…