22-Java状态模式 ( State Pattern )

news2024/11/18 6:42:07

Java状态模式

    • 摘要
    • 实现
    • 范例

  • 状态模式(State Pattern)中类的行为是基于它的状态改变的

  • 在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象

  • 状态模式属于行为型模式

摘要

1. 意图

  • 允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类

2. 主要解决

  • 对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为

3. 何时使用

  • 代码中包含大量与对象状态有关的条件语句

4. 如何解决

  • 将各种具体的状态类抽象出来

5. 关键代码

通常命令模式的接口中只有一个方法。而状态模式的接口中有一个或者多个方法
而且,状态模式的实现类的方法,一般返回值,或者是改变实例变量的值
也就是说,状态模式一般和对象的状态有关。实现类的方法有不同的功能,覆盖接口中的方法
状态模式和命令模式一样,也可以用于消除 if…else 等条件选择语句

6. 应用实例

  • 打篮球的时候运动员可以有正常状态、不正常状态和超常状态;
  • 曾侯乙编钟中,’钟是抽象接口’,’钟A’等是具体状态,’曾侯乙编钟’是具体环境(Context);

7. 优点

  • 封装了转换规则;
  • 枚举可能的状态,在枚举状态之前需要确定状态种类;
  • 将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为;
  • 允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块;
  • 可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数;

8. 缺点

  • 状态模式的使用必然会增加系统类和对象的个数;
  • 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱;
  • 状态模式对”开闭原则”的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应类的源代码;

9. 使用场景

  • 行为随状态改变而改变的场景;
  • 条件、分支语句的代替者;

10. 注意事项

  • 在行为受状态约束的时候使用状态模式,而且状态不超过 5 个

实现

在这里插入图片描述

  • 我们将创建一个 StateInterface 接口和实现了 StateInterface 接口的实体状态类。
  • Context 是一个带有某个状态的类
  • StatePatternDemo ,我们的演示类使用 Context 和状态对象来演示 Context 在状态改变时的行为变化

范例

1. 创建一个接口 StateInterface

StateInterface.java

package com.demo.gof;
public interface StateInterface {
   public void doAction(Context context);
}

2. 创建实现接口的实体类

StartState.java

package com.demo.gof;
public class StartState implements StateInterface {

   public void doAction(Context context) {
      System.out.println("Player is in start state");
      context.setState(this);   
   }

   public String toString(){
      return "Start State";
   }
}

StopState.java

package com.demo.gof;
public class StopState implements StateInterface {

   public void doAction(Context context) {
      System.out.println("Player is in start state");
      context.setState(this);   
   }

   public String toString(){
      return "Stop State";
   }
}

3. 创建 Context 类

Context.java

package com.demo.gof;
public class Context {
   private State state;

   public Context(){
      state = null;
   }

   public void setState(State state){
      this.state = state;       
   }

   public State getState(){
      return state;
   }
}

4. 使用 Context 来查看当状态 State 改变时的行为变化

StatePatternDemo.java

package com.demo.gof;
public class StatePatternDemo {
   public static void main(String[] args) {
      Context context = new Context();

      StartState startState = new StartState();
      startState.doAction(context);

      System.out.println(context.getState().toString());

      StopState stopState = new StopState();
      stopState.doAction(context);

      System.out.println(context.getState().toString());
   }
}

编译运行以上 Java 范例,输出结果如下

$ javac -d . src/main/com.demo/gof/StatePatternDemo.java
$ java  com.demo.gof.StatePatternDemo
Player is in start state
Start State
Player is in stop state
Stop State

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

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

相关文章

深入解析HashMap:结构与哈希函数揭秘一

文章目录 一、HashMap的基本结构1.数组与链表的结构1.1 数组1.2 链表 2.红黑树的简单介绍3.Node节点的组成 二、HashMap的哈希函数1.hashCode()方法的作用2.位运算与哈希值的计算3.扰动函数的作用 思考:为什么HashMap源码中使用位运算 在Java编程语言中,…

『 Linux 』进程替换( Process replacement ) 及 简单Shell的实现(万字)

文章目录 🦄 进程替换🦩 execl()函数🦩 execlp()函数🦩 execle()函数🦩 execv()函数🦩 execvp()函数🦩 execvpe()函数🦩 execve()函数 🦄 简单Shell命令行解释器的实现&a…

区块链基础知识(上):区块链基本原理、加密哈希、公钥加密

目录 基本原理 加密哈希: 公钥加密: 希望有人向你发送只有你才能打开的加密文档/消息时使用 PKC 希望向其他人发送加密文档/消息并证明它确实由你发送时使用 PKC 使用 PKC 和加密哈希对文档/消息进行数字签名 交易哈希链使用数字签名转让数字资产所…

Docker进阶:深入了解 Dockerfile

Docker进阶:深入了解 Dockerfile 一、Dockerfile 概述二、Dockerfile 优点三、Dockerfile 编写规则四、Dockerfile 中常用的指令1、FROM2、LABEL3、RUN4、CMD5、ENTRYPOINT6、COPY7、ADD8、WORKDIR9、 ENV10、EXPOSE11、VOLUME12、USER13、注释14、ONBUILD 命令15、…

算法刷题Day9 | 28. 实现 strStr()、459.重复的子字符串、字符串总结

目录 0 引言1 实现 strStr()1.1 我的解题1.2 KMP算法解题 2 重复的子字符串2.1 暴力求解2.2 KMP求解法 3 字符串总结 🙋‍♂️ 作者:海码007📜 专栏:算法专栏💥 标题:算法刷题Day8 | 28. 实现 strStr()、45…

画图实战-Python实现某产品全年销量数据多种样式可视化

画图实战-Python实现某产品全年销量数据多种样式可视化 学习心得Matplotlib说明什么是Matplotlib?Matplotlib特性Matplotlib安装 产品订单量-折线图某产品全年订单量数据数据提取和分析绘制折线图 产品订单&销售额-条形图某产品全年订单&销售额数据绘制条形…

【嵌入式学习】C++day03.14

一、思维导图 二、练习 成员函数版本实现算术运算符的重载 全局函数版本实现算术运算符的重载 #include <iostream>using namespace std;class Num {friend const Num operator-(const Num &L,const Num &R); private:int a;int b; public://运算符重载const …

【Linux系统编程】进程的退出与等待

进程的创建 fork()用于创建子进程。但fork创建的子进程获得的是父进程&#xff08;即调用 fork() 的进程&#xff09;的一份几乎完全相同的副本&#xff0c;包括父进程的代码、数据、堆、栈和数据结构等内容。当进程调用fork后&#xff0c;一旦控制转移到内核中的fork代码后&am…

ATTRIBUTE_HELPER_HEADER

ATTRIBUTE_HELPER_HEADER是ns3中的一个宏定义&#xff0c;用于声明类类型的属性值、访问器和检查器。 例如&#xff1a; ATTRIBUTE_HELPER_HEADER (QueueSize);此宏声明&#xff1a; 属性值类typeValue&#xff0c;属性访问器函数MaketypeAccessor&#xff0c;AttributeChec…

CesiumJS 沙盒

CesiumJS 沙盒 通过CesiumJS 沙盒快速测试CesiumJS的一些功能&#xff0c;免去安装开发环境的困恼。 Hello World https://sandcastle.cesium.com/index.html 简单修改&#xff08;F8运行&#xff09;&#xff1a;去掉界面上UI const viewer new Cesium.Viewer("cesi…

C++中的STL-string类

文章目录 一、为什么学习string类&#xff1f;1.1 C语言中的字符串 二、准库中的string类2.2 string类2.3 string类的常用接口说明2.4 string类对象的容量操作2.5 string类对象的访问及遍历操作2.5 string类对象的修改操作2.7 string类非成员函数2.8 模拟实现string 一、为什么…

C++特性之一:继承

1. 派生类的成员变量、成员函数、构造、析构 2. 继承的切片 3. 重定义/隐藏 重定义/隐藏&#xff1a;派生类和基类有同名的成员&#xff0c;就叫隐藏。派生类的成员隐藏了基类的成员。 隐藏时可以通过类作用限定符来访问被隐藏的成员。 class Person { public:void Print(){…

一文了解Spring的SPI机制

文章目录 一文了解Spring的SPI机制Java SPIServiceLoader Spring SPISpringboot利用Spring SPI开发starter 一文了解Spring的SPI机制 Java SPI SPI 全称 Service Provider Interface &#xff0c;是 Java提供的一套用来被第三方实现或者扩展的接口&#xff0c;它可以用来启用…

考研数学——高数:高斯公式

助记: 关于积分时什么时候可以将变量整体代入积分式的问题&#xff1a;在积分过程中&#xff0c;如果某一整体恒为常量&#xff0c;则可以直接替换为定值&#xff0c;常见于对线或面的积分。 而在这题&#xff0c;用高斯公式之前是面积分&#xff0c;如果有这个整体出现的话是…

寒假作业Day 11

寒假作业Day 11 一、选择题 栈满的判断&#xff1a;在链式存储结构中&#xff0c;栈的大小是动态的&#xff0c;只受限于系统分配给程序的内存大小。因此&#xff0c;理论上&#xff0c;链式栈不会因为空间不足而“满”。所以&#xff0c;不需要判断栈满。 栈空的判断&#xf…

解决VS编译中文报错 error C2001:常量中有换行符

产生原因&#xff1a;文件中有中文字符&#xff0c;但是文件是utf-8格式的&#xff0c;使用msvc编译器编译时就会产生上述错误 首先说明&#xff1a;我是通过方法2解决该问题的。 解决办法&#xff1a; 方式1&#xff1a; 通过把源文件转换为gbk编码&#xff0c;但是只能一…

TCP和UDP基础

tcp服务器及客户端链接 ucd服务器及客户端

python自学7

第二章第一节面向对象 程序的格式都不一样&#xff0c;每个人填写的方式也有自己的习惯&#xff0c;比如收集个人信息&#xff0c;可能有人用字典字符串或者列表&#xff0c; 类的成员方法 类和对象 构造方法 挨个传输值太麻烦了&#xff0c;也没有方便点的&#xff0c;有&…

4_springboot_shiro_jwt_多端认证鉴权_Redis存储会话

1. 什么是会话 所谓的会话&#xff0c;就是用户与应用程序在某段时间内的一系列交互&#xff0c;在这段时间内应用能识别当前访问的用户是谁&#xff0c;而且多次交互中可以共享数据。我们把一段时间内的多次交互叫做一次会话。 即用户登录认证后&#xff0c;多次与应用进行交…

WPF —— Calendar日历控件详解

1&#xff1a; Calendar的简介 日历控件用于创建可视日历&#xff0c;让用户选择日期并在选择日期时触发事件。 DisplayMode 用来调整日历显示模式&#xff0c;分为Month、Year 和Decade 三种。如下是None 2&#xff1a;Calendar控件常用的属性 SelectionMode 选中日历的类…