目录
状态模式定义
优点
缺点
状态模式结构说明
工作流程
代码示例
应用场景
本质
设计原则
相关设计模式
示例和开源框架中的应用
状态模式定义
当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了类。状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
优点
-
封装性:状态模式将状态和行为封装在不同的类中,使系统更加模块化和可维护。
-
可扩展性:通过添加新的具体状态类,可以轻松地扩展系统的行为,而不需要修改现有的代码。
-
松散耦合:上下文对象与具体状态类之间的耦合较低,状态之间的切换也不会影响到客户端代码。
缺点
-
类数量增加:引入状态模式可能会增加系统中的类数量,特别是在有多个状态和行为的情况下。
-
逻辑分散:状态模式将对象的状态分散到多个状态类中,可能会导致系统的逻辑分散,难以理解和维护。
状态模式结构说明
-
上下文(Context):维护一个对当前状态对象的引用,它可以根据不同的状态委托给具体的状态对象来执行相应的行为。
-
抽象状态类(Abstract State):定义了一个接口或抽象类,用于表示不同状态所对应的行为。
-
具体状态类(Concrete State):实现了抽象状态类定义的接口或抽象方法,以实现特定状态下的行为。
工作流程
-
上下文对象维护对当前状态对象的引用。
-
客户端通过上下文对象触发特定的操作。
-
上下文对象根据当前状态对象的不同,将操作委托给具体状态对象来执行相应的行为。
-
具体状态对象执行特定状态下的行为。
代码示例
状态模式属于行为型设计模式。 这个模式倏忽间想到了身边的狐朋狗友,“醉了没”,“没醉”,“那你抱着垃圾箱喊半天兄弟了,还要聊么”?本质是不同状态下不同行为,那就读读苏轼吧。
1.创建抽象状态类
public interface State { void writePoetry(); }
2.创建具体状态类,少年YoungAdult、成年TwentySomething、中年MiddleAge和暮年Elderly.
// 少年 - 不妨闲处袖手看风云 public class YoungAdult implements State{ @Override public void writePoetry() { System.out.println("当时共客长安,似二陆初来俱少年。"); System.out.println("有笔头千字,胸中万卷;致君尧舜,此事何难?"); System.out.println("用舍由时,行藏在我,袖手何妨闲处看。"); System.out.println("身长健,但优游卒岁,且斗尊前。"); } }
// 成年 - 进士及第前程远大 public class TwentySomething implements State{ @Override public void writePoetry() { System.out.println("人生到处知何似,应似飞鸿踏雪泥。"); System.out.println("泥上偶然留指爪,鸿飞那复计东西。"); System.out.println("老僧已死成新塔,坏壁无由见旧题。"); System.out.println("往日崎岖还记否,路长人困蹇驴嘶。"); } }
// 中年 - 思念亡妻十年情深 public class MiddleAge implements State{ @Override public void writePoetry() { System.out.println("十年生死两茫茫,不思量,自难忘。"); System.out.println("千里孤坟,无处话凄凉。"); System.out.println("纵使相逢应不识,尘满面,鬓如霜。"); System.out.println("夜来幽梦忽还乡,小轩窗,正梳妆。"); System.out.println("相顾无言,惟有泪千行。"); System.out.println("料得年年肠断处,明月夜,短松冈。"); } }
// 暮年 - 九死不悔倨傲自信 public class Elderly implements State{ @Override public void writePoetry() { System.out.println("参横斗转欲三更,苦雨终风也解晴。"); System.out.println("云散月明谁点缀?天容海色本澄清。"); System.out.println("空余鲁叟乘桴意,粗识轩辕奏乐声。"); System.out.println("九死南荒吾不恨,兹游奇绝冠平生。"); } }
3.客户端,通过改变状态表现不同的行为
public class StateClient { public static void main(String[] args) { SuShi suShi = new SuShi(); System.out.println("=========年少时的苏轼==========="); suShi.setState(new YoungAdult()); suShi.life(); System.out.println("=========成年时的苏轼==========="); suShi.setState(new TwentySomething()); suShi.life(); System.out.println("=========中年时的苏轼==========="); suShi.setState(new MiddleAge()); suShi.life(); System.out.println("=========暮年时的苏轼==========="); suShi.setState(new Elderly()); suShi.life(); } }
应用场景
-
当一个对象的行为取决于其内部状态,并且在不同状态下需要执行不同的行为时,可以考虑使用状态模式。
-
当一个对象有多个状态转换,并且状态之间的转换逻辑复杂时,状态模式可以简化状态切换的管理。
-
当需要将状态的具体实现分离出来,以便可以独立添加或修改状态时,状态模式非常有用。
本质
状态模式的本质是将对象的状态和与状态相关的行为封装到不同的状态类中,从而实现状态的可切换性。
设计原则
-
开闭原则(Open-Closed Principle):状态模式遵循开闭原则,因为可以通过添加新的具体状态类来扩展系统的行为。
相关设计模式
-
状态模式通常与策略模式(Strategy Pattern)有一定的相似之处,因为它们都涉及将不同的行为封装到不同的类中。不同之处在于,策略模式主要用于定义一组算法,而状态模式主要用于表示一个对象在不同状态下的行为。
示例和开源框架中的应用
-
电梯控制系统:电梯可以处于不同的状态,如运行、停止、开门、关门等。状态模式可以用于管理电梯的状态和相应的行为。
-
文档编辑器:文档编辑器中的文档可以处于不同的编辑状态,如编辑、预览、保存等。状态模式可以用于管理文档的编辑状态和相应的编辑行为。
-
计算器应用程序:计算器应用程序中的计算过程可以处于不同的状态,如输入数字、选择操作、执行计算等。状态模式可以用于管理计算器的不同状态和相应的操作。文章来源:https://uudwc.com/A/JwkWG
-
Spring框架 - 事务管理:Spring框架中的事务管理可以使用状态模式来管理不同事务状态(如开始、提交、回滚)的行为。不同事务状态对应不同的具体状态类。文章来源地址https://uudwc.com/A/JwkWG