状态模式包含以下几个角色:java
● Context(环境类):环境类又称为上下文类,它是拥有多种状态的对象。因为环境类的状态存在多样性且在不一样状态下对象的行为有所不一样,所以将状态独立出去造成单独的状态类。在环境类中维护一个抽象状态类State的实例,这个实例定义当前状态,在具体实现时,它是一个State子类的对象。 ● State(抽象状态类):它用于定义一个接口以封装与环境类的一个特定状态相关的行为,在抽象状态类中声明了各类不一样状态对应的方法,而在其子类中实现类这些方法,因为不一样状态下对象的行为可能不一样,所以在不一样子类中方法的实现可能存在不一样,相同的方法能够写在抽象状态类中。 ● ConcreteState(具体状态类):它是抽象状态类的子类,每个子类实现一个与环境类的一个状态相关的行为,每个具体状态类对应环境的一个具体状态,不一样的具体状态类其行为有所不一样
一、主要优势测试
(1) 封装了状态的转换规则,在状态模式中能够将状态的转换代码封装在环境类或者具体状态类中,能够对状态转换代码进行集中管理,而不是分散在一个个业务方法中。 (2) 将全部与某个状态有关的行为放到一个类中,只须要注入一个不一样的状态对象便可使环境对象拥有不一样的行为。 (3) 容许状态转换逻辑与状态对象合成一体,而不是提供一个巨大的条件语句块,状态模式可让咱们避免使用庞大的条件语句来将业务方法和状态转换代码交织在一块儿。 (4) 可让多个环境对象共享一个状态对象,从而减小系统中对象的个数
二、主要缺点this
(1) 状态模式的使用必然会增长系统中类和对象的个数,致使系统运行开销增大。 (2) 状态模式的结构与实现都较为复杂,若是使用不当将致使程序结构和代码的混乱,增长系统设计的难度。 (3) 状态模式对“开闭原则”的支持并不太好,增长新的状态类须要修改那些负责状态转换的源代码,不然没法转换到新增状态;并且修改某个状态类的行为也需修改对应类的源代码。
三、适用场景设计
(1) 对象的行为依赖于它的状态(如某些属性值),状态的改变将致使行为的变化。 (2) 在代码中包含大量与对象状态有关的条件语句,这些条件语句的出现,会致使代码的可维护性和灵活性变差,不能方便地增长和删除状态,而且致使客户类与类库之间的耦合加强。
王者荣耀中的状态模式(李信光、暗形态):code
/** * 2018/12/6 * 状态模式的切换类 * * @author machuanpeng */ public class LiXinContext { private int stateInt; private State state; public LiXinContext() { this.stateInt = 0; this.state = new OriginalState(); } public State getState() { return state; } public void setState(State state) { this.state = state; } public int getStateInt() { return stateInt; } public void setStateInt(int stateInt) { this.stateInt = stateInt; } public void bigOperation() { // 释放大招 state.bigOperation(this); } }
/** * 2018/12/6 * State * * @author machuanpeng */ public abstract class State { public void bigOperation(LiXinContext context) }
/** * 2018/12/6 * 初始形态 * * @author machuanpeng */ public class OriginalState extends State { public void bigOperation(LiXinContext context) { if(context.getStateInt()==0){ System.out.println("原始形态没有大招!"); }else{ context.setState(new LightState()); context.bigOperation(); } } }
/** * 2018/12/6 * 光形态 * * @author machuanpeng */ public class LightState extends State { public void bigOperation(LiXinContext context) { if(context.getStateInt()==1){ System.out.println("光形态蓄力,三道光!"); }else if(context.getStateInt()<1){ context.setState(new OriginalState()); context.bigOperation(); }else if(context.getStateInt()>1){ context.setState(new DarkState()); context.bigOperation(); } } }
/** * 2018/12/6 * 暗形态 * * @author machuanpeng */ public class DarkState extends State { public void bigOperation(LiXinContext context) { if(context.getStateInt()==2){ System.out.println("暗形态拍地板,弹起对方!"); }else{ context.setState(new LightState()); context.bigOperation(); } } }
测试:对象
public class Client { public static void main(String args[]) { LiXinContext context = new LiXinContext(); context.bigOperation(); context.setStateInt(1); context.bigOperation(); } }