【行为型模式】状态模式

devtools/2024/9/24 10:22:28/

一、状态模式概述

        状态模式的定义:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。(对象行为型)

策略模式和状态模式是双胞胎,在出生时才分开。

  • 策略模式是围绕可以互换的算法来创建成功业务的。
  • 状态模式走的是更崇高的路,它通过改变对象内部的状态来帮助对象控制自己的行为。
  • 状态模式的优缺点
    • 优点
      • 1.可以将不同的状态隔离;
      • 2.每个状态都是一个单独的类;
      • 3.可以将各种状态的转换逻辑 , 分布到状态的子类中 ,减少相互依赖;
      • 4.增加新状态操作简单。
    • 缺点
      • 如果状态数量比较多,状态类的数量会增加,业务场景系统变得很复杂;
      • 如果业务中某个对象由几十上百个状态,就会很复杂,这时就需要对状态进行拆分处理。
  • 适用场景
    • 一个对象存在多个状态,状态可以相互转换;
    • 不同状态下,行为不同。

二、代码实现

        状态模式主要包含三个角色:

  • 环境(Context)角色:也称为上下文,它定义了客户感兴趣的接口,维护一个当前状态,并将与状态相关的操作委托给当前状态对象来处理;
  • 抽象状态(State)角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为;
  • 具体状态(Concrete State)角色:实现抽象状态所对应的行为。
        2.1 环境角色(GumballMachine)
package state.CandySolder;
//环境角色
public class GumballMachine {private State noQuarterState;private State hasQuarterState;private State soldState;private State soldOutState;private State state = soldOutState; // 糖果机默认状态为售罄状态int count = 0; // 糖果库存量public GumballMachine(int numberGumballs) {noQuarterState = new NoQuarterState(this);hasQuarterState = new HasQuarterState(this);soldState = new SoldState(this);soldOutState = new SoldOutState(this);count = numberGumballs;if (numberGumballs > 0) {state = noQuarterState; // 如果采购了糖果球(numberGumballs>0),则糖果机的状态为未投币状态}}// 投入钱币public void insertQuarter() {state.insertQuarter();}// 退出钱币public void ejectQuarter() {state.ejectQuarter();}// 扭转曲柄public void turnCrank() {state.turnCrank();state.dispense();}// 减少库存public void releaseBall() {if (count > 0) {System.out.println("一个糖果球正在出库");--count;} else {System.out.println("库存不足,一个糖果球无法出库");}}// 设置状态void setState(State state) {this.state = state;}//get,set方法public State getNoQuarterState() {return noQuarterState;}public State getSoldOutState() {return soldOutState;}public void setSoldOutState(State soldOutState) {this.soldOutState = soldOutState;}public int getCount() {return count;}public void setCount(int count) {this.count = count;}public void setNoQuarterState(State noQuarterState) {this.noQuarterState = noQuarterState;}public State getHasQuarterState() {return hasQuarterState;}public void setHasQuarterState(State hasQuarterState) {this.hasQuarterState = hasQuarterState;}public State getSoldState() {return soldState;}public void setSoldState(State soldState) {this.soldState = soldState;}}
        2.2 抽象状态(State)
package state.CandySolder;
//抽象角色
public interface State {void insertQuarter(); // 投入硬币操作   void ejectQuarter(); // 退出硬币操作void turnCrank(); // 扭转曲柄操作void dispense(); // 发放糖果操作
}
        2.3 具体状态(HasQuarterState、NoQuarterState、SoldOutState、SoldState)
package state.CandySolder;
//具体状态,已经投放钱币状态
public class HasQuarterState implements State {private GumballMachine gumballMachine;public HasQuarterState(GumballMachine gumballMachine) {this.gumballMachine = gumballMachine;}@Overridepublic void insertQuarter() {// TODO Auto-generated method stubSystem.out.println("您已经投入钱币!无须再次投入钱币!");}@Overridepublic void ejectQuarter() {// TODO Auto-generated method stubSystem.out.println("退款成功!");gumballMachine.setState(gumballMachine.getNoQuarterState()); // 状态流转}@Overridepublic void turnCrank() {// TODO Auto-generated method stubSystem.out.println("正在出货中,请稍等");gumballMachine.setState(gumballMachine.getSoldState()); // 状态流转}@Overridepublic void dispense() {// TODO Auto-generated method stubSystem.out.println("你还没有扭转曲柄,糖果不可以发放!");}}
package state.CandySolder;
//具体状态,没有投放钱币状态
public class NoQuarterState implements State {private GumballMachine gumballMachine;public NoQuarterState(GumballMachine gumballMachine) {this.gumballMachine = gumballMachine;}@Overridepublic void insertQuarter() {// TODO Auto-generated method stubSystem.out.println("投入钱币成功!");gumballMachine.setState(gumballMachine.getHasQuarterState()); // 状态流转}@Overridepublic void ejectQuarter() {// TODO Auto-generated method stubSystem.out.println("你还没有投入钱币,不能退回钱币!");}@Overridepublic void turnCrank() {// TODO Auto-generated method stubSystem.out.println("你还没有投入钱币,不能扭转曲柄!");}@Overridepublic void dispense() {// TODO Auto-generated method stubSystem.out.println("你还没有投入钱币,糖果不可以发放!");}}
package state.CandySolder;
//具体状态,糖果售空状态
public class SoldOutState implements State {private GumballMachine gumballMachine;public SoldOutState(GumballMachine gumballMachine) {this.gumballMachine = gumballMachine;}@Overridepublic void insertQuarter() {// TODO Auto-generated method stubSystem.out.println("糖果已经售罄。不能投入钱币");}@Overridepublic void ejectQuarter() {// TODO Auto-generated method stubSystem.out.println("退回钱币成功!");}@Overridepublic void turnCrank() {// TODO Auto-generated method stubSystem.out.println("糖果已经售罄。不能扭转曲柄!");}@Overridepublic void dispense() {// TODO Auto-generated method stubSystem.out.println("糖果已经售罄。糖果无法出售!");}}
package state.CandySolder;
//具体状态,糖果售卖状态
public class SoldState implements State {private GumballMachine gumballMachine;public SoldState(GumballMachine gumballMachine) {this.gumballMachine = gumballMachine;}@Overridepublic void insertQuarter() {// TODO Auto-generated method stubSystem.out.println("糖果正在出货中,请稍等。无须再次投入钱币!");}@Overridepublic void ejectQuarter() {// TODO Auto-generated method stubSystem.out.println("糖果正在出货中,请稍等。不能退回钱币!");}@Overridepublic void turnCrank() {// TODO Auto-generated method stubSystem.out.println("糖果正在出货中,请稍等。不需要再次扭转曲柄!");}@Overridepublic void dispense() {// TODO Auto-generated method stubif (gumballMachine.getCount() > 0) {System.out.println("糖果正在出货中,请稍等!");gumballMachine.releaseBall();gumballMachine.setState(gumballMachine.getNoQuarterState()); // 状态流转} else {System.out.println("糖果库存不足,无法出货!");gumballMachine.setState(gumballMachine.getSoldOutState()); // 状态流转}}}
        2.4 main方法实现状态模式
package state.CandySolder;
//测试
public class Test {public static void main(String[] args) {System.out.println("-----向糖果机中放入1枚糖果-----");GumballMachine machine = new GumballMachine(1);System.out.println("-----第一次购买糖果-----");machine.insertQuarter();machine.ejectQuarter();machine.turnCrank();System.out.println("-----第二次购买糖果-----");machine.insertQuarter();machine.turnCrank();System.out.println("-----第三次购买糖果-----");machine.insertQuarter();machine.turnCrank();machine.ejectQuarter();}
}
        2.5 UML图

三、代码结构图


http://www.ppmy.cn/devtools/8779.html

相关文章

python创建sqlite,并使用flask-sqlalchemy连接

python创建sqlite,并使用flask-sqlalchemy连接 在 PyCharm 中,你可以使用 SQLite 数据库来存储数据。以下是在 PyCharm 中使用 SQLite 数据库并通过 Flask-SQLAlchemy 连接它的步骤: 1. 在 PyCharm 中创建 SQLite 数据库 打开 PyCharm&…

【ARFoundation自学01】搭建AR框架+检测平面+点击克隆立方体到地面=自信入门!

介绍 AR 的功能其实是个大手机系统厂商和眼镜设备厂商开发的功能,并不是Unity的功能,毕竟Unity没有自己的手机设备!比如谷歌公司的安卓开发了ARcore,让所有安卓8.0版本以上的用户能够在手机上体验AR功能!苹果推出了AR…

《ElementUI 基础知识》png 图片扩展 icon用法

前言 UI 设计给的切图是 .png 格式。但想与 Element UI icon 用法类似,方案如下。 实现 步骤一 准备图片 步骤二 新建文件,可使用 CSS 预处理语言 styl 或 scss。 stylus 方式 文件 icon.styl /* 定义一个混合 */ cfgIcon(w, h) {display: inlin…

【Linux】简单的线程池

目录 线程池介绍 基本概念 定义 组成部分 线程池的优点 资源高效 响应迅速 可管理性 线程池的工作原理 线程池的使用场景 线程池的注意事项 实现简单的线程池 前置函数 Mutex 类介绍 LockGuard 类介绍 Log类的介绍 枚举定义 Log类 全局对象 Conf类 myThre…

华为ensp中MSTP多网段传输协议(原理及配置命令)

作者主页:点击! ENSP专栏:点击! 创作时间:2024年4月22日15点29分 在华为ENSP中,MSTP(多段传输协议)是重要的生成树协议,它扩展了STP(生成树协议&#xff09…

如何封装Vue组件并上传到npm

前言 环境准备 1.注册npm账号:npm | Home (npmjs.com) 2.保证当前环境安装了vue、webpack、node,以下工作将在该环境下进行(没有的小伙伴自行百度安装哈~) 3.一下用到的环境版本 webpack:v5.1.4node:v…

基于SpringBoot的在线五子连珠的设计与实现,前端采用vue框架;后端采用SpringBoot,mybatis

介绍 基于SpringBoot的在线五子连珠的设计与实现,主要是设计一款五子棋游戏,涉及登录注册的功能,人机对战、联机对战和积分排行榜的功能。其中人机对战中,电脑采用的是采用了一种基于局面分析的评分算法来确定机器人的下一步落子…

Linux操作系统·Linux简介

1.世界上第一个完善的网络操作系统 Unix是1969年由美国电话电报公司(AT&T)贝尔实验室的两个工程师所创造的操作系统,它允许计算机同时处理多用户和程序。目前大型政府单位、大型企业、航空公司、金融机构多在使用,价钱昂贵,但性能和稳定性…