状态模式:
当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类。
使用前提:
主要解决当控制一个对象状态转换的条件表达式过于复杂时的情况,把状态的逻辑判断转移到不同状态的一系列类中,可以把复杂的逻辑简化。
优点:
找出应用中需要变化之处,将它们独立出来,不和那些不需要变化的代码混合在一起,业务逻辑类中,将判断分离出“业务逻辑实现类”中,简化其编码和功能。业务逻辑实现类,只是一个平台,提供管理业务逻辑中的动作,而不是具体的操作实现。
缺点:
导致设计中类的数目大量增加。
注意:
状态之间的转换。①State的转换可以在在状态的处理类内部完成, 但是这样会带来的问题是各个State之间出现了关联, 那么如果一个State本身改变(减少, 增加) 会带来很大影响, 你就有可能看看当前发生改变的state是否也影响到了其它的state的执行。②State的转换也可以由其它类调用Context的setState()来完成, 感觉这种情况更不可靠, 因为这样的话其他类就必须知道Context的特定State, 带来了不必要的耦合, 因此建议对setState()的调用尽量放在Context和State这两处。
state的创建和销毁。两个方法: 1.在context内部创建所有state, 一直维护从不销毁.2.在状态转换的时候才创建, 然后上一个state由JVM自动回收. 主要原则需要看实际情况是Context的State的变化是否频繁, 如果不频繁, 建议用第二种,比较优雅。
如何选择者两种方式:(1)如果状态转换的规则是一定的,一般不需要进行什么扩展规则,那么就适合在上下文中统一进行状态的维护;(2)如果状态的转换取决于前一个状态动态处理的结果,或者是依赖外部数据,为了增强灵活性,这种情况下,一般式在状态处理类中进行状态的维护。
环境(Context)角色(上下文):客户程序是通过它来满足自己的需求,定义客户端所感兴趣的接口,并且保留一个状态类接口的引用(具体化:具体状态角色的实例)。这个具体状态类的实例给出此环境对象的现有状态。
抽象状态(State)角色:定义一个状态接口,用以封装环境(Context)对象的一个特定的状态所对应的行为。
具体状态(ConcreteState)角色:每一个具体状态类都实现了环境(Context)的一个状态所对应的行为。
public interface State {
public void shot();
}
public class NormalState implements State{
@Override
public void shot() {
System.out.println("10 中 5");
}
}
public class NonormalState implements State{
@Override
public void shot() {
System.out.println("10中1");
}
}
public class SuperState implements State{
@Override
public void shot() {
System.out.println("10 中 9");
}
}
public class Player {
private State state = new NormalState();
public void setState(State state){
this.state = state;
}
public void shot(){
state.shot();
}
}
public class TestState {
public static void main(String[] args) {
Player player = new Player();
player.shot();
player.setState(new NonormalState());
player.shot();
player.setState(new SuperState());
player.shot();
}
}