1.概述
1.1 定义
在很多情况下,一个对象的行为取决于一个或多个动态变化的属性,这样的属性叫做状态,这样的对象叫做有状态的对象,对象状态是从事先定义好的一系列☞中取出的,当这样一个对象与外部事件产生互动时,其内部状态就会改变,使得系统的行为也发生改变,即类的行为是基于它的状态而改变的。
1.2 解决问题
对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。
1.3 使用场景
1.行为随状态改变而改变的场景 2.条件、分支语句的代替者 1.4 应用实例
王者荣耀里面游戏人物有正常状态和开大状态。
2.类图
3.角色
Context 表示环境类,定义了客户应用程序感兴趣的接口,并维护一个ConcreteState子类的实例,这个实例用于
定义当前状态。
State 表示抽象状态类,定义了一个接口以封装与Context的一个特定状态相关的行为。 ConcreteStateA 表示具体状态类,每一个具体状态类实现一个与Context的一个状态相关的行为。
4.优缺点
4.1 优点
1.封装了转换规则。 2.枚举可能的状态,在枚举状态之前需要确定状态种类。 3.将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。 4.允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。 5.可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。 4.2 缺点
1.增加系统类和对象的个数。 2.状态模式封装了状态的转换过程,但是它需要枚举可能的状态,因此,需要事先确定状态种类,这也导致在状态模式中增加
新的状态类时会违反开闭原则。
3.状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。
5.案例
5.1 说明
这里以机器人开火为例,正常状态下,每秒开枪1次;兴奋状态下,每秒开枪2次。
5.2 代码
1)环境类:机器人
/** * 环境类:机器人 * @author Administrator */ public class Marine { private State state; public Marine() { state = null; } public State getState() { return state; } public void setState(State state) { this.state = state; } }
2)抽象状态类
/** * 抽象状态类 * @author Administrator */ public interface State { //机器人开火方法 public void fire(Marine marine); }
3)具体状态:正常状态
/** * 具体状态类:正常状态下的机器人 * @author Administrator */ public class NormalState implements State{ @Override public void fire(Marine marine) { System.out.println("普通状态每秒开枪1次"); marine.setState(this); } }
4)具体状态:兴奋状态
/** * 具体状态类:兴奋状态下的机器人 * @author Administrator */ public class ExcitedState implements State{ @Override public void fire(Marine marine) { System.out.println("兴奋状态每秒开枪2次"); marine.setState(this); } }
5)客户端类
/** * 客户端类 * @author Administrator */ public class Client { public static void main(String[] args) { Marine marine = new Marine(); NormalState normalState = new NormalState(); normalState.fire(marine); ExcitedState excitedState = new ExcitedState(); excitedState.fire(marine); } }
5.3 效果
普通状态每秒开枪1次 兴奋状态每秒开枪2次
5.4 分析