State Pattern 状态模式

允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。状态模式是一种对象行为型模式。 对象的行为依赖于它的状态,并且可以在运行时根据状态改变行为。 代码中包含大量与对象状态有关的if/else语句,这些条件对应于对象的各种状态,这些冗余条件语句的出现导致代码的可维护性和灵活性变差,这种情况适合使用状态模式进行优化。

State Pattern 状态模式

State Pattern的初步实现

  • 该种方法会造成代码膨胀,并且不易于扩展。
    1. 定义一个接口,定义多种状态以及多种行为。 ```Java public interface ILift { public static final int OPENING_STATE = 1; public static final int CLOSE_STATE = 2; public static final int RUNNING_STATE = 3; public static final int STOPPING_STATE = 4; /**
    • @Description: Set state of current object.
    • @Return: void */ public void setState(int state); public void open(); public void close(); public void run(); public void stop(); } ```
  1. 实现接口,利用switch来实现多种状态下的行为
    public class Lift implements ILift {
     private int state;
     @Override
     public void setState(int state) {
         this.state = state;
     }
     @Override
     public void open() {
         switch (this.state) {	//利用switch-case语句,实现在多种状态下物体的行为。
         // 如果当前状态是打开,则什么都不做。
         case OPENING_STATE:
             break;
         case CLOSE_STATE:
             this.openWithoutLogic();
             break;
         case RUNNING_STATE:
             break;
         case STOPPING_STATE:
             this.openWithoutLogic();
             break;
         default:
             break;
         }
     }
     @Override
     public void close() {
         switch (this.state) {
         case OPENING_STATE:
             closeWithoutLogic();
             break;
         case CLOSE_STATE:
             break;
         case RUNNING_STATE:
             break;
         case STOPPING_STATE:
             break;
         default:
             break;
         }
     }
     @Override
     public void run() {
         switch (this.state) {
         case OPENING_STATE:
             break;
         case CLOSE_STATE:
             runWithoutLogic();
             break;
         case RUNNING_STATE:
             break;
         case STOPPING_STATE:
             runWithoutLogic();
             break;
         default:
             break;
         }
     }
     @Override
     public void stop() {
         switch (this.state) {
         case OPENING_STATE:
             break;
         case CLOSE_STATE:
             stopWithoutLogic();
             break;
         case RUNNING_STATE:
             stopWithoutLogic();
             break;
         case STOPPING_STATE:
             break;
         default:
             break;
         }
     }
     private void openWithoutLogic(){
         System.out.println("Elevator open.");
         setState(OPENING_STATE);
     }
     private void closeWithoutLogic(){
         System.out.println("Elevator close.");
         setState(CLOSE_STATE);
     }
     private void runWithoutLogic(){
         System.out.println("Elevator run.");
         setState(RUNNING_STATE);
     }
     private void stopWithoutLogic(){
         System.out.println("Elevator stop.");
         setState(STOPPING_STATE);
     }
     public static void main(String[] args) {
         ILift elevator = new Lift();
         elevator.setState(STOPPING_STATE);
         elevator.open();
         elevator.close();
         elevator.run();
         elevator.stop();
     }
    }
    

State Pattern的实现流程

  1. Context类,定义客户端所感兴趣的接口,并且内部维护一个具体状态类的实例,从而维护了对象的现有状态。
    public class Context extends AbstractLift{
     public final static OpenState OPEN_STATE = new OpenState();	//定义了几个状态
     public final static CloseState CLOSE_STATE = new CloseState();
     public final static RunState RUN_STATE = new RunState();
     public final static StopState STOP_STATE = new StopState();
     private AbstractLift liftState;	//具体状态类的实例
     public AbstractLift getLiftState() {
         return liftState;
     }
     public void setLiftState(AbstractLift liftState) {
         this.liftState = liftState;
         this.liftState.setContext(this);	//记得要设置Context的实例。
     }
     @Override
     public void open() {
         liftState.open();	//利用具体状态实例调用行为。
     }
     @Override
     public void close() {
         liftState.close();
     }
     @Override
     public void run() {
         liftState.run();
     }
     @Override
     public void stop() {
         liftState.stop();
     }
    }
    
  2. State:抽象状态类或状态接口,用以抽象封装行为。
    public interface ILiftState {
     public void open();
     public void close();
     public void run();
     public void stop();
    }
    public abstract class AbstractLift implements ILiftState {
     protected Context context;	//持有一个Context类,用于获取状态
     public void setContext(Context context){
         this.context = context;
     }
    }
    
  3. ConcreteState类:具体状态类,实现了State中的抽象方法。
    • RunState
      public class RunState extends AbstractLift {
       @Override
       public void open() {	//当前状态无法切换到的状态
       }
       @Override
       public void close() {
       }
       @Override
       public void run() {	//在当前状态中调用当前行为,执行行为
         System.out.println("Elevator runs.");
       }
       @Override
       public void stop() {	//当前状态可以转换到的状态,切换状态并执行行为
         context.setLiftState(Context.STOP_STATE);
         context.getLiftState().stop();
       }
      }
      
  • StopState ```Java public class StopState extends AbstractLift { @Override public void open() { super.context.setLiftState(Context.OPEN_STATE); super.context.getLiftState().open(); } @Override public void close() { } @Override public void run() { super.context.setLiftState(Context.RUN_STATE); super.context.getLiftState().run(); } @Override public void stop() { System.out.println(“Elevator stops.”); } }

* CloseState
```Java
public class CloseState extends AbstractLift {
	@Override
	public void open() {
		context.setLiftState(Context.OPEN_STATE);
		context.getLiftState().open();
	}
	@Override
	public void close() {
		System.out.println("Elevator close.");
	}
	@Override
	public void run() {
		context.setLiftState(Context.RUN_STATE);
		context.getLiftState().run();
	}
	@Override
	public void stop() {
		context.setLiftState(Context.STOP_STATE);
		context.getLiftState().stop();
	}
}
  • OpenState
    public class OpenState extends AbstractLift {
      @Override
      public void open() {
          System.out.println("Elevator opens.");
      }
      @Override
      public void close() {
          context.setLiftState(Context.CLOSE_STATE);
          context.getLiftState().close();
      }
      @Override
      public void run() {
      }
      @Override
      public void stop() {
      }
    }
    
  1. 测试
    public class Client {
     public static void main(String[] args) {
         Context context = new Context();
         context.setLiftState(new CloseState());
         context.open();
         context.close();
         context.run();
         context.stop();
     }
    }
    Elevator opens.
    Elevator close.
    Elevator runs.
    Elevator stops.