状态模式

来源:互联网 发布:系统还原数据会丢失吗 编辑:程序博客网 时间:2024/05/19 16:34

状态模式:

当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类。

使用前提:

主要解决当控制一个对象状态转换的条件表达式过于复杂时的情况,把状态的逻辑判断转移到不同状态的一系列类中,可以把复杂的逻辑简化。

优点:

找出应用中需要变化之处,将它们独立出来,不和那些不需要变化的代码混合在一起,业务逻辑类中,将判断分离出“业务逻辑实现类”中,简化其编码和功能。业务逻辑实现类,只是一个平台,提供管理业务逻辑中的动作,而不是具体的操作实现。

缺点:

导致设计中类的数目大量增加。

注意:

状态之间的转换。①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();
}
}


0 0