Gof23种设计模式(21)——状态模式(State)

2020年8月14日10:25:00 评论 77

1 基础知识

1.1 标准定义

状态(State)模式标准定义:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

1.2 分析和说明

状态(State)模式属于对象行为型模式。状态模式允许一个对象在其内部状态改变的时候改变行为。这个对象看上去象是改变了它的类一样。可理解为在不同的上下文中,相同的动作导致的结果不同。状态模式把所研究的对象的行为包装在不同的状态对象里,每一个状态对象都属于一个抽象状态类的一个子类。状态模式的意图是让一个对象在其内部状态改变的时候,其行为也随之改变。状态模式需要对每一个系统可能取得的状态创立一个状态类的子类。当系统的状态变化时,系统便改变所选的子类。

使用State模式可以将不同状态下的行为分隔开来,这样做的好处是很容易增加新的状态并实现状态转换而不影响已存在的状态和上下文环境。同时还避免了操作中庞大的条件分支语句,使代码更容易维护。

状态(State)模式结构如图1,其角色包括抽象状态(State)角色、具体状态(Concrete State)角色和环境(Context)角色。

Gof23种设计模式(21)——状态模式(State)图1 状态模式结构

 抽象状态(State)角色:定义一个接口,用以封装环境(Context)对象的一个特定的状态所对应的行为。

 具体状态(Concrete State)角色:每一个具体状态类都实现了环境(Context)的一个状态所对应的行为。

 环境(Context)角色:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出此环境对象的现有状态。

2 应用场景举例

比如公司的项目有这么几个状态,项目立项、项目开发、项目试运行、项目验收、项目维护、项目结项等状态。当项目启动的时候,工作是要进行项目立项工作。当项目立项完成后,接下来的工作是项目开发。项目开发完成后,项目的工作变成了项目试运行。当项目试运行完成了,进入了项目验收。当项目验收后,进行项目维护,维护工作结束后,最后是项目结项。整个项目就全部完成了。所以,项目在不同的状态有不同的工作内容。通过设置项目的状态,我们可以知道应该对不同状态的项目采取什么样的工作了。其状态图如图2所示。

Gof23种设计模式(21)——状态模式(State)

图2 状态模式状态图

在这里可以把State抽象类理解为抽象状态(State)角色。ProjectBuilderState类、ProjectDevelopmentState类、ProjectMaintenanceState类、ProjectRunState类和ProjectEndState类是具体状态(Concrete State)角色。Project类是环境(Context)角色。其结构类图如图3所示。ProjectBuilderState类、ProjectDevelopmentState类、ProjectMaintenanceState类、ProjectRunState类和ProjectEndState类继承State抽象类。Project类关联State抽象类,即State类是Project类的一个属性。

Gof23种设计模式(21)——状态模式(State)图3 状态模式类图

状态模式实现顺序图见图4,实现顺序描述:
①基于Project类创建一个projectA对象;
②-⑥分别创建bullder对象、development对象、run对象、maintenance对象、end对象等状态对象。
⑦调用projectA对象的setCurrentState方法,把bullder对象赋值给projectA;
⑧调用projectA对象的doCurrentWork方法,显示当前projectA对象的工作内容;
⑨-⑩与⑦-⑧方式相同,只不过是修改projectA对象的状态为development对象,并显示projectA对象在development状态下的工作内容;(11)-(12)与⑦-⑧方式相同,只不过是修改projectA对象的状态为run对象,并显示projectA对象在run状态下的工作内容;(13)-(14)与⑦-⑧方式相同,只不过是修改projectA对象的状态为maintenance对象,并显示projectA对象在maintenance状态下的工作内容;(15)-(16)与⑦-⑧方式相同,只不过是修改projectA对象的状态为end对象,并显示projectA对象在end状态下的工作内容。

Gof23种设计模式(21)——状态模式(State)图4 状态模式实现顺序图

Project对象的状态由各个属性的当前值构成。当我们调用某个对象的setxxx(),通常表示修改它的xxx属性。另外,Project对象在执行方法时,也可能修改自己的状态。对象的状态可能是决定其行为的关键因素,依赖于状态的代码逻辑可能遍布于类的大量方法。State模式的目标就是简化这类代码,把依赖于状态的逻辑集中到一组类,每一个类代表一种不同的状态,避免if语句嵌套过深或过于复杂,转而依赖于多态性来调用不同的方法。

Project定义客户感兴趣的接口,并维护一个State子类的实例,这个实例定义了当前的状态。State类定义一个接口以封装与Project的一个特定状态相关的行为。ProjectBuilderState、ProjectDevelopmentState、ProjectMaintenanceState、ProjectRunState和ProjectEndState实现与Project的一个状态相关的行为。Project将与状态相关的请求委托给当前的State对象处理。Project可将自身作为一个参数传递给处理该请求的状态对象。这使得状态对象在必要时可访问Project。Project是客户使用的主要接口。客户可用状态对象来配置一个Project,一旦一个Project配置完毕,它的客户不再需要直接与状态对象打交道。Project或State子类都可决定哪个状态是另外哪一个的后继者,以及是在何种条件下进行状态转换。

3.Java的实现程序代码

Java程序实现主要包括Project类文件,State抽象类文件,ProjectBuilderState类文件、ProjectDevelopmentState类文件、ProjectMaintenanceState类文件、ProjectRunState类文件和ProjectEndState类文件等7个文件。其关系如图3所示。下面分别列出这7个文件的程序代码,最后列出测试代码并显示输出结果。

Project类程序代码清单01所示。

程序代码清单01

public class Project {

	private String projectName;
	private State currentState;

	public Project(String projectName) {
		super();
		this.projectName = projectName;
	}

	public String getProjectName() {
		return projectName;
	}

	public void setProjectName(String projectName) {
		this.projectName = projectName;
	}

	public void setCurrentState(State state) {
		currentState = state;
	}

	public void doCurrentWork() {
		currentState.doWork(this);
	}
}

State抽象类程序代码清单02所示。

程序代码清单02

public abstract class State {
	public void doWork(Project project) {
	}
}

ProjectBuilderState类、ProjectDevelopmentState类、ProjectMaintenanceState类、ProjectRunState类和ProjectEndState类继承State抽象类,其程序代码清单03所示。

程序代码清单03

public class ProjectBuilderState extends State {

	public void doWork(Project project) {
		System.out.println(project.getProjectName() + "正在进行立项工作");
	}
}

public class ProjectDevelopmentState extends State {

	public void doWork(Project project) {
		System.out.println(project.getProjectName() + "正在进行开发工作");
	}
}

public class ProjectMaintenanceState extends State {

	public void doWork(Project project) {
		System.out.println(project.getProjectName() + "正在进行维护工作");
	}
}

public class ProjectRunState extends State {

	public void doWork(Project project) {
		System.out.println(project.getProjectName() + "正在进行试运行工作");
	}
}

public class ProjectEndState extends State {

	public void doWork(Project project) {
		System.out.println(project.getProjectName() + "正在进行结项工作");
	}
}

状态模式测试程序的代码清单04如下:

程序代码清单04

public class Client {

	public static void main(String[] args) {

		ProjectBuilderState bullder = new ProjectBuilderState();
		ProjectDevelopmentState development = new ProjectDevelopmentState();

		ProjectRunState run = new ProjectRunState();
		ProjectMaintenanceState maintenance = new ProjectMaintenanceState();
		ProjectEndState end = new ProjectEndState();

		Project projectA = new Project("projectA");

		System.out.println("——————设置项目为立项状态——————");
		
		projectA.setCurrentState(bullder);
		projectA.doCurrentWork();

		System.out.println("——————设置项目为开发状态——————");

		projectA.setCurrentState(development);
		projectA.doCurrentWork();

		System.out.println("——————设置项目为试运行状态——————");

		projectA.setCurrentState(run);
		projectA.doCurrentWork();

		System.out.println("——————设置项目为维护状态——————");

		projectA.setCurrentState(maintenance);
		projectA.doCurrentWork();

		System.out.println("——————设置项目为结项状态——————");

		projectA.setCurrentState(end);
		projectA.doCurrentWork();
	}
}

状态模式测试类输出结果如下所示:

——————设置项目为立项状态——————
projectA正在进行立项工作
——————设置项目为开发状态——————
projectA正在进行开发工作
——————设置项目为试运行状态——————
projectA正在进行试运行工作
——————设置项目为维护状态——————
projectA正在进行维护工作
——————设置项目为结项状态——————
projectA正在进行结项工作

4 扩展和说明

状态实际上就是对象的多态性的表现。

State模式适用于下面两种情况:

(1)一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。

(2)一个操作中含有庞大的多分支的条件语句。且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。通常,有多个操作包含这一相同的条件结构。

State模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。

使用State模式可以将不同状态下的行为分隔开来,这样做的好处是很容易增加新的状态并实现状态转换而不影响已存在的状态和上下文环境。同时还避免了操作中庞大的条件分支语句,使代码更容易维护。


参考链接

11种行为型模式

Gof23种设计模式(13)——解释器模式(Interpreter)
Gof23种设计模式(14)——模板方法模式(Template Method)
Gof23种设计模式(15)——责任链模式(Chain of Responsibility)
Gof23种设计模式(16)——命令模式(Command)
Gof23种设计模式(17)——迭代器模式(Iterator)
Gof23种设计模式(18)——中介者模式(Mediator)
Gof23种设计模式(19)——备忘录模式(Memento)
Gof23种设计模式(20)——观察者模式(Observer)
Gof23种设计模式(21)——状态模式(State)
Gof23种设计模式(22)——策略模式(Strategy)
Gof23种设计模式(23)——访问者模式(Visitor)
Gof23种设计模式 —— 行为型模式总结和比较

回到总目录Gof23种设计模式(全解析)

(转载自微信公众号:架构设计模式)

素课网
  • 本文由 发表于 2020年8月14日10:25:00
  • 转载请注明:https://www.suketech.com/9285.html
设计模式:面向对象设计的六大原则 - 总结 设计模式

设计模式:面向对象设计的六大原则 – 总结

开闭原则是面向对象设计中最基础的设计原则,它指导我们如何建立稳定灵活的系统。开闭原则可能是设计模式六项原则中定义最模糊的一个了,它只告诉我们对扩展开放,对修改关闭,可是到底如何才能做到对扩展开放,对修...
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: