Java中的状态模式实例教程

简介:

原文链接 作者:Pankaj Kumar 译者:f0tlo <1357654289@qq.com>

状态模式是一种行为设计模式。适用于当对象的内在状态改变它自身的行为时。

如果想基于对象的状态来改变自身的行为,通常利用对象的状态变量及if-else条件子句来扮演针对对象的不同行为。状态模式Context(环境)State(状态)分离的方式既保证状态与行为的联动变化,又使得这种变化是条理明晰且松耦合的。

Context是包含了状态引用的类,此引用指向一个状态的具体实现。并且帮助把对状态的请求委托给此状态的对象进行处理。看一个具体的例子。

假如想实现电视遥控器,使用简单按键来表现动作。如果状态是ON,电视将被打开,如果状态是OFF,电视将被关闭。

利用if-else条件子句来实现。


package com.journaldev.design.state;

public class TVRemoteBasic {

 private String state="";

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

 public void doAction(){
 if(state.equalsIgnoreCase("ON")){
 System.out.println("TV is turned ON");
 }else if(state.equalsIgnoreCase("OFF")){
 System.out.println("TV is turned OFF");
 }
 }

 public static void main(String args[]){
 TVRemoteBasic remote = new TVRemoteBasic();

 remote.setState("ON");
 remote.doAction();

 remote.setState("OFF");
 remote.doAction();
 }

}


注意:客户端代码需要知道每一个不同的值所代表的遥控器的不同状态。如果这样,假如大量的状态被增加,那么对于被紧紧捆绑在一起的状态实现以及相应的客户端代码,它们的维护及扩展就变得非常困难。

现在使用状态模式实现上述电视控制器。

抽象State接口

首先创建一个状态接口来定义一个方法,此方法需要被不同的具体状态类以及环境类实现。


package com.journaldev.design.state;

public interface State {

 public void doAction();
}


具体State实现

自此例子中,包含两个状态:一个是打开电视的状态,一个关闭电视的状态。因此,需要创建两个具体状态类代表这两个行为。


package com.journaldev.design.state;

public class TVStartState implements State {

 @Override
 public void doAction() {
 System.out.println("TV is turned ON");
 }

}
package com.journaldev.design.state;

public class TVStopState implements State {

 @Override
 public void doAction() {
 System.out.println("TV is turned OFF");
 }

}


现在我们开始实现Context对象,能改基于内在对象来改变自身的行为。

Context类实现


package com.journaldev.design.state;

public class TVContext implements State {

 private State tvState;

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

 public State getState() {
 return this.tvState;
 }

 @Override
 public void doAction() {
 this.tvState.doAction();
 }

}


注意,Context类实现了状态以及保持了对此状态的引用。它能够把对此状态的请求委托到某一具体状态实现中。

测试程序

完成一个简单地程序对使用状态模式的电视遥控器的测试。


package com.journaldev.design.state;

public class TVRemote {

 public static void main(String[] args) {
 TVContext context = new TVContext();
 State tvStartState = new TVStartState();
 State tvStopState = new TVStopState();

 context.setState(tvStartState);
 context.doAction();

 context.setState(tvStopState);
 context.doAction();

 }

}


上述程序的输出与没用使用任何设计模式的电视控制器的实现类似。

使用状态设计模式的优势就是实现多态性的过程是清晰可见的。状态的改变中产生的错误也较少,另外增加更多的状态以及行为变得容易且更具鲁棒性。此外状态模式也帮助避免if-else子句或者switch-case条件判定逻辑。

状态模式类似于策略模式,请看Java中的策略模式。这就是全部的状态设计模式,希望你喜欢上它了。

目录
相关文章
|
2月前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
|
23天前
|
安全 Java 编译器
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
|
23天前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
|
23天前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
Kotlin教程笔记(28) -Kotlin 与 Java 混编
|
2月前
|
Java
通过Java代码解释成员变量(实例变量)和局部变量的区别
本文通过一个Java示例,详细解释了成员变量(实例变量)和局部变量的区别。成员变量属于类的一部分,每个对象有独立的副本;局部变量则在方法或代码块内部声明,作用范围仅限于此。示例代码展示了如何在类中声明和使用这两种变量。
|
9天前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
Kotlin教程笔记(28) -Kotlin 与 Java 混编
10 0
|
2月前
|
JSON Java Maven
实现Java Spring Boot FCM推送教程
本指南介绍了如何在Spring Boot项目中集成Firebase云消息服务(FCM),包括创建项目、添加依赖、配置服务账户密钥、编写推送服务类以及发送消息等步骤,帮助开发者快速实现推送通知功能。
73 2
|
2月前
|
Java 数据库连接 编译器
Kotlin教程笔记(29) -Kotlin 兼容 Java 遇到的最大的“坑”
Kotlin教程笔记(29) -Kotlin 兼容 Java 遇到的最大的“坑”
|
2月前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
本系列教程笔记详细讲解了Kotlin语法,适合希望深入了解Kotlin的开发者。对于需要快速学习Kotlin的小伙伴,推荐查看“简洁”系列教程。本篇笔记重点介绍了Kotlin与Java混编的技巧,包括代码转换、类调用、ProGuard问题、Android库开发建议以及相互调用时的注意事项。
26 3
|
2月前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
Kotlin教程笔记(28) -Kotlin 与 Java 混编
22 3
下一篇
无影云桌面