当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。
这种模式看起来类似于“策略”模式,但有一个关键的区别。在状态模式中,特定状态可能彼此了解,并开始从一个状态过渡到另一个状态,而策略几乎永远不会彼此了解。
【角色】
- 抽象状态角色(State):接口或抽象类,负责对象状态定义,并且封装环境角色以实现状态切换。
- 具体状态角色(ConcreteState):每一个具体状态必须完成两个职责:本状态的行为管理以及趋向状态处理,通俗地说,就是本状态下要做的事情,以及本状态如何过渡到其他状态。
- 环境角色(Context):定义客户端需要的接口,并且负责具体状态的切换。
【优点】
- 符合单一职责原则:将与特定状态相关的代码组织到单独的类中。
- 符合开放封闭原则:在不更改现有状态类或上下文的情况下引入新状态。
【缺点】
- 如果有很多种状态,子类会太多,类膨胀。一个事物有很多个状态也不稀奇,如果完全使用状态模式就会有太多的子类,不好管理。
如果类只有几个状态或很少更改,应用状态模式可能会过度设计。
/*** 抽象状态类*/public abstract class State {/*** 台灯*/protected Lamp lamp;public State(Lamp lamp) {this.lamp = lamp;}/*** 切换灯光*/abstract void change();}
/*** 正常光状态** @author yupan* @date 7/18/21 12:29 PM*/public class NormalState extends State {public NormalState(Lamp lamp) {super(lamp);System.out.println("正常光");}@Overridepublic void change() {// 变成"强光"super.lamp.setState(new HighState(super.lamp));}}
/*** 强光状态*/public class HighState extends State {public HighState(Lamp lamp) {super(lamp);System.out.println("强光");}@Overridepublic void change() {// 变成"弱光"super.lamp.setState(new LowState(super.lamp));}}
/*** 弱光状态*/public class LowState extends State {public LowState(Lamp lamp) {super(lamp);System.out.println("弱光");}@Overridepublic void change() {// 变成"关闭"super.lamp.setState(new CloseState(super.lamp));}}
/*** 关闭状态*/public class CloseState extends State {public CloseState(Lamp lamp) {super(lamp);System.out.println("关闭");}@Overridepublic void change() {// 变成"正常光"super.lamp.setState(new NormalState(super.lamp));}}
/*** 台灯*/public class Lamp {private State state;public Lamp() {// 默认关闭状态this.state = new CloseState(this);}public void setState(State state) {this.state = state;}public void click() {this.state.change();}}
public class StateTest {public static void main(String[] args) {// 台灯默认关闭Lamp lamp = new Lamp();// 正常光lamp.click();// 强光lamp.click();// 弱光lamp.click();// 关闭lamp.click();// 正常光lamp.click();}}----输出----关闭正常光强光弱光关闭正常光
