设计模式之状态模式(上)

news2024/11/25 7:09:35
状态模式
1)概述
1.定义

允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。

2.作用

状态模式用于解决系统中复杂对象的状态转换以及不同状态下行为的封装问题

3.方案

状态模式将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象状态可以灵活变化,对于客户端而言,无须关心对象状态的转换以及对象所处的当前状态,客户端都可以一致处理。

4.结构图

在这里插入图片描述

5.角色

Context(环境类):环境类又称为上下文类,它是拥有多种状态的对象,在环境类中维护一个抽象状态类State的实例,这个实例定义当前状态,在具体实现时,它是一个State子类的对象。

State(抽象状态类):定义一个接口以封装与环境类的一个特定状态相关的行为,在抽象状态类中声明了各种不同状态对应的方法,而在其子类中实现类这些方法,由于不同状态下对象的行为可能不同,因此在不同子类中方法的实现可能存在不同,相同的方法可以写在抽象状态类中

ConcreteState(具体状态类):它是抽象状态类的子类,每一个子类实现一个与环境类的一个状态相关的行为,每一个具体状态类对应环境的一个具体状态,不同的具体状态类其行为有所不同。

6.代码实现

抽象状态类

abstract class State {
  //声明抽象业务方法,不同的具体状态类可以不同的实现
	public abstract void handle();
}

具体状态类

public class ConcreteState extends State {
	public void handle() {
		//方法具体实现代码
	}
}

环境类

public class Context {
  //维持一个对抽象状态对象的引用
	private State state; 
	//其他属性值,该属性值的变化可能会导致对象状态发生变化
	private int value; 
 
    //设置状态对象
	public void setState(State state) {
		this.state = state;
	}
 
	public void request() {
		//调用状态对象的业务方法
		state.handle(); 
	}
}

在状态模式的使用过程中,一个对象的状态之间还可以进行相互转换,通常有两种实现状态转换的方式。

统一由环境类来负责状态之间的转换:环境类充当了状态管理器(State Manager)角色,在环境类的业务方法中通过对某些属性值的判断实现状态转换,还可以提供一个专门的方法用于实现属性判断和状态转换。

	……
  public void changeState() {
		  //判断属性值,根据属性值进行状态转换
      if (value == 0){
			  this.setState(new ConcreteStateA());
		  }else if (value == 1){
			  this.setState(new ConcreteStateB());
		  }
	}
  ……

由具体状态类负责状态之间的转换:在具体状态类的业务方法中判断环境类的某些属性值再根据情况为环境类设置新的状态对象,实现状态转换,也可以提供一个专门的方法来负责属性值的判断和状态转换,此时,状态类与环境类之间存在依赖或关联关系,因为状态类需要访问环境类中的属性值。

	……
  public void changeState(Context ctx) {
		//根据环境对象中的属性值进行状态转换
    if (ctx.getValue() == 1){
			ctx.setState(new ConcreteStateB());
		}else if (ctx.getValue() == 2){
			ctx.setState(new ConcreteStateC());
		}
  }
  ……
2)完整解决方案
1.结构图

在这里插入图片描述

Account充当环境类角色,AccountState充当抽象状态角色,NormalState、OverdraftState和RestrictedState充当具体状态角色。

2.代码实现
//银行账户:环境类
public class Account {
  //维持一个对抽象状态对象的引用
	private AccountState state; 
	//开户名
	private String owner; 
	//账户余额
	private double balance = 0; 
	
	public Account(String owner,double init) {
		this.owner = owner;
		this.balance = balance;
		//设置初始状态
		this.state = new NormalState(this); 
		System.out.println(this.owner + "开户,初始金额为" + init);	
		System.out.println("---------------------------------------------");	
	}
	
	public double getBalance() {
		return this.balance;
	}
	
	public void setBalance(double balance) {
		this.balance = balance;
	}
	
	public void setState(AccountState state) {
		this.state = state;
	}
	
	public void deposit(double amount) {
		System.out.println(this.owner + "存款" + amount);
		//调用状态对象的deposit()方法
		state.deposit(amount); 
		System.out.println("现在余额为"+ this.balance);
		System.out.println("现在帐户状态为"+ this.state.getClass().getName());
		System.out.println("---------------------------------------------");			
	}
	
	public void withdraw(double amount) {
		System.out.println(this.owner + "取款" + amount);
		//调用状态对象的withdraw()方法
    state.withdraw(amount); 
		System.out.println("现在余额为"+ this.balance);
		System.out.println("现在帐户状态为"+ this. state.getClass().getName());		
		System.out.println("---------------------------------------------");
	}
	
	public void computeInterest()
	{ 
	  //调用状态对象的computeInterest()方法
		state.computeInterest(); 
	}
}
 
//抽象状态类
abstract class AccountState {
	protected Account acc;
	public abstract void deposit(double amount);
	public abstract void withdraw(double amount);
	public abstract void computeInterest();
	public abstract void stateCheck();
}
 
//正常状态:具体状态类
public class NormalState extends AccountState {
	public NormalState(Account acc) {
		this.acc = acc;
	}
 
  public NormalState(AccountState state) {
		this.acc = state.acc;
	}
		
	public void deposit(double amount) {
		acc.setBalance(acc.getBalance() + amount);
		stateCheck();
	}
	
	public void withdraw(double amount) {
		acc.setBalance(acc.getBalance() - amount);
		stateCheck();
	}
	
	public void computeInterest()
	{
		System.out.println("正常状态,无须支付利息!");
	}
	
    //状态转换
	public void stateCheck() {
		if (acc.getBalance() > -2000 && acc.getBalance() <= 0) {
			acc.setState(new OverdraftState(this));
		}
		else if (acc.getBalance() == -2000) {
			acc.setState(new RestrictedState(this));
		}
		else if (acc.getBalance() < -2000) {
			System.out.println("操作受限!");
		}	
	}   
}  
 
//透支状态:具体状态类
public class OverdraftState extends AccountState
{
	public OverdraftState(AccountState state) {
		this.acc = state.acc;
	}
	
	public void deposit(double amount) {
		acc.setBalance(acc.getBalance() + amount);
		stateCheck();
	}
	
	public void withdraw(double amount) {
		acc.setBalance(acc.getBalance() - amount);
		stateCheck();
	}
	
	public void computeInterest() {
		System.out.println("计算利息!");
	}
	
  //状态转换
	public void stateCheck() {
		if (acc.getBalance() > 0) {
			acc.setState(new NormalState(this));
		}
		else if (acc.getBalance() == -2000) {
			acc.setState(new RestrictedState(this));
		}
		else if (acc.getBalance() < -2000) {
			System.out.println("操作受限!");
		}
	}
}
 
//受限状态:具体状态类
public class RestrictedState extends AccountState {
	public RestrictedState(AccountState state) {
		this.acc = state.acc;
	}
	
	public void deposit(double amount) {
		acc.setBalance(acc.getBalance() + amount);
		stateCheck();
	}
	
	public void withdraw(double amount) {
		System.out.println("帐号受限,取款失败");
	}
	
	public void computeInterest() {
		System.out.println("计算利息!");
	}
	
    //状态转换
	public void stateCheck() {
		if(acc.getBalance() > 0) {
			acc.setState(new NormalState(this));
		}
		else if(acc.getBalance() > -2000) {
			acc.setState(new OverdraftState(this));
		}
	}
}

客户端测试类

public class Client {
	public static void main(String args[]) {
		Account acc = new Account("段誉",0.0);
		acc.deposit(1000);
		acc.withdraw(2000);
		acc.deposit(3000);
		acc.withdraw(4000);
		acc.withdraw(1000);
		acc.computeInterest();
	}
}

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

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

相关文章

RabbitMQ 各种通信模式的Python实现

一、RabbitMQ 原理 1、基本原理 RabbitMQ是流行的开源消息队列系统&#xff0c;用erlang语言开发。RabbitMQ是AMQP&#xff08;高级消息队列协议&#xff09;的标准实现。支持多种客户端&#xff0c;如&#xff1a;Python、Java、Javascript、C#、C/C,Go等&#xff0c;支持AJ…

【ENSP】华为三层交换机配置AAA认证,开启telnet服务

配置步骤 1.给交换机配置ip地址&#xff0c;以便登陆 2.配置AAA&#xff0c;用户名&#xff0c;密码&#xff0c;服务类型&#xff0c;用户权限 3.配置接入设备的数量 4.开启telnet服务 LSW2交换机配置 u t m #关闭提示 sys …

微信小程序scroll-view组件

一、介绍 当一个容器内容很多时&#xff0c;若容器无法显示完整内容&#xff0c;则可通过滚动操作查看所有内容 在微信小程序中scroll-view组件可以实现滚动效果 二、scroll-view组件的属性值 &#xff08;1&#xff09;scroll-x 【boolean型】 允许横向滚动条&#xff0c;默…

Python也可以合并和拆分PDF,批量高效!

PDF是最方便的文档格式&#xff0c;可以在任何设备原样且无损的打开&#xff0c;但因为PDF不可编辑&#xff0c;所以很难去拆分合并。 知乎上也有人问&#xff0c;如何对PDF进行合并和拆分&#xff1f; 看很多回答推荐了各种PDF编辑器或者网站&#xff0c;确实方法比较多。 …

HBase的数据模型与架构

官方文档&#xff1a;Apache HBase – Apache HBase™ Homehttps://hbase.apache.org/ 一、HBase概述 1.概述 HBase的技术源自Google的BigTable论文&#xff0c;HBase建立在Hadoop之上&#xff0c;是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统&#xff0c;用于…

ThreadLocal和ThreadLocalHashMap

请直接百度详细介绍 -------------------------------------------------------------------------------------------------------------------------------- 1.ThreadLocalMap是Thread类里的一个局部变量 2.ThreadLocalMap是ThreadLocal类里的一个静态内部类, 3.ThreadL…

Backend - DRF 序列化(django-rest-framework)

目录 一、restful 、django-rest-framework 、swagger 三者的关系 &#xff08;一&#xff09;restful API&#xff08;REST API&#xff09; 1. rest 2. restful 3. api 4. restfulAPI &#xff08;二&#xff09;django-rest-framework&#xff08;简称DRF&#xff09…

分类算法——模型选择与调优(三)

交叉验证 交叉验证&#xff1a;将拿到的训练数据&#xff0c;分为训练和验证集。以下图为例&#xff1a;将数据分成4份&#xff0c;其中 一份作为验证集。然后经过4次&#xff08;组&#xff09;的测试&#xff0c;每次都更换不同的验证集。即得到4组模型的 结果&#xff0c;取…

进程间通信--共享内存

1.共享内存介绍 共享内存为多个进程之间共享和传递数据提供了一种有效的方式。共享内存是先在物 理内存上申请一块空间,多个进程可以将其映射到自己的虚拟地址空间中。 所有进 程都可以访问共享内存中的地址,就好像它们是由 malloc 分配的一样。如果某个进 程向共享内存写入了…

随着深度学习的兴起,浅层机器学习没有用武之地了吗?

深度学习的兴起确实在许多领域取得了显著的成功&#xff0c;尤其是那些涉及大量数据和复杂模式的识别任务&#xff0c;如图像识别、语音识别和自然语言处理等。然而&#xff0c;这并不意味着浅层机器学习&#xff08;如支持向量机、决策树、朴素贝叶斯等&#xff09;已经失去了…

Achronix FPGA增加对Bluespec提供的基于Linux的RISC-V软处理器的支持,以实现可扩展数据处理

Bluespec支持加速器功能的RISC-V处理器将Achronix的FPGA转化为可编程SoC 2024年4月——高性能FPGA芯片和嵌入式FPGA&#xff08;eFPGA&#xff09;硅知识产权&#xff08;IP&#xff09;领域的领先企业Achronix半导体公司&#xff0c;以及RISC-V工具和IP领域的行业领导者Blues…

Matlab分段微分方程组拟合【案例源码+视频教程】

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《复杂函数拟合案例分享》本专栏旨在提供 1.以案例的形式讲解各类复杂函数拟合的程序实现方法&#xff0c;并提供所有案例完整源码&#xff1b;2.…

OpenHarmony开发实例:【新闻客户端】

介绍 本篇Codelab我们将教会大家如何构建一个简易的OpenHarmony新闻客户端&#xff08;JS版本&#xff09;。应用包含两级页面&#xff0c;分别是主页面和详情页面&#xff0c;两个页面都展示了丰富的UI组件&#xff0c;其中详情页的实现逻辑中还展示了如何通过调用相应接口&a…

【Java NIO】那NIO为什么速度快?

Java IO在工作中其实不常用到&#xff0c;更别提NIO了。但NIO却是高效操作I/O流的必备技能&#xff0c;如顶级开源项目Kafka、Netty、RocketMQ等都采用了NIO技术&#xff0c;NIO也是大多数面试官必考的体系知识。虽然骨头有点难啃&#xff0c;但还是要慢慢消耗知识、学以致用哈…

百度智能云万源全新一代智能计算操作系统发布:引领AI新纪元,开启智能未来

随着科技的迅猛发展&#xff0c;人工智能&#xff08;AI&#xff09;逐渐渗透到我们生活的每个角落&#xff0c;为人类社会带来前所未有的变革。在这场科技革命的浪潮中&#xff0c;百度作为中国AI领域的领军企业&#xff0c;始终站在技术创新的前沿&#xff0c;不断引领行业发…

【架构-14】数据库性能优化方式

数据库出现性能瓶颈对外的表现为&#xff1a; 大量请求阻塞SQL操作变慢存储出现问题 为解决上述出现的问题&#xff0c;因此推出了一系列的数据库性能优化方式。 数据库性能优化是提高数据库系统性能和响应时间的关键任务。以下是一些常见的 数据库性能优化方式&#xff1a; …

在Qt中如何简单设计一个文件和图像浏览器

文本浏览器 设计一个文本浏览器程序&#xff0c;可以打开、显示 txt、html等文件。 1.在Qt Designer中设计一个菜单其中包含打开和退出选项&#xff1a; 2. 在 QMainWindow 构造函数中把 textBrower 设为主窗口的中心部件&#xff0c;这样整个窗口就成了包含 textBrower 的单文…

免费的 ChatGPT、GPTs、AI绘画(国内版)

&#x1f525;博客主页&#xff1a;白云如幻❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ ChatGPT3.5、GPT4.0、GPTs、AI绘画相信对大家应该不感到陌生吧&#xff1f;简单来说&#xff0c;GPT-4技术比之前的GPT-3.5相对来说更加智能&#xff0c;会根据用户的要求生成多种内容甚…

Elasticsearch的使用教程

Elasticsearch简介 Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎&#xff0c;能够解决不断涌现出的各种用例。作为 Elastic Stack 的核心&#xff0c;Elasticsearch 会集中存储您的数据&#xff0c;让您飞快完成搜索&#xff0c;微调相关性&#xff0c;进行…

【读论文】【泛读】三篇生成式自动驾驶场景生成: Bevstreet, DisCoScene, BerfScene

文章目录 1. Street-View Image Generation from a Bird’s-Eye View Layout1.1 Problem introduction1.2 Why1.3 How1.4 My takeaway 2. DisCoScene: Spatially Disentangled Generative Radiance Fields for Controllable 3D-aware Scene Synthesis2.1 What2.2 Why2.3 How2.4…