天天看点

STATE PATTERN(状态)模式描述实现适用场景优点缺点相关模式

文章目录

  • 描述
    • 定义
    • 类型
    • 动机
    • UML类图
    • 时序图
  • 实现
    • 主要角色
    • 示例
  • 适用场景
  • 优点
  • 缺点
  • 相关模式
STATE PATTERN(状态)模式描述实现适用场景优点缺点相关模式

描述

定义

允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。

类型

对象行为型模式

动机

对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。

UML类图

STATE PATTERN(状态)模式描述实现适用场景优点缺点相关模式

时序图

STATE PATTERN(状态)模式描述实现适用场景优点缺点相关模式

实现

主要角色

  • Context:上下文
    • 定义客户感兴趣的接口。
    • 维护一个ConcreteState子类的实例,这个实例定义当前状态。
  • State:状态接口类
    • 定义一个接口以封装与Context的一个特定状态相关的行为。
  • ConcreteState:具体状态类
    • 每一子类实现一个与Context的一个状态相关的行为。

示例

  • Context:上下文。谁定义状态转换:如果规则是固定的,那么可在Context中完全实现。然而若让State子类自身指定后继状态以及何时进行转换,通常更灵活更合适,但缺点是在各子类之间产生了实现依赖。
    public class Context {
         private State state;
    
         public Context(State state) {
            this.state = state;
         }
       
         public State getState() {
            return state;
         }
    
         public void changeState() {
      	  this.state = this.state.next();
         }
    
         public void request() {
            state.handle(this); 
         }
      }
               
  • State:状态接口类。创建和销毁State对象通常有两种做法:1) 仅当需要State对象时才创建它们并随后销毁它们;2) 提前创建它们并且始终不销毁它们。
    interface State {
         void handle(Context context);
         State next();
      }
               
  • ConcreteState:具体状态类
    public class ConcreteState1 implements State {
         @override
         public void next() {
            return new ConcreteState2();
         }
    
         @override
         public void handle(Context context) {
            System.out.println("ConcreteState1");
         }
      }
    
      public class ConcreteState2 implements State {
         @override
         public void next() {
            return new ConcreteState1();
         }
    
         @override
         public void handle(Context context) {
            System.out.println("ConcreteState2");
         }
      }
               
  • Client:客户类
    public class Client {
          public static void main(String[] args) {
              Context context = new Context(new ConcreteState1());
      		context.request();
      		context.changeState();
      		context.request();
          }
      }
               

适用场景

  • 对象的行为随它的状态改变而改变,并且它必须在运行时刻动态决定。
  • 条件、分支语句的代替者。一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。

优点

  • 将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
  • 封装了转换规则。通过定义新的子类可以很容易的增加新的状态和转换。
  • 使得状态转换显式化。为不同的状态引入独立的对象使得转换变得更加明确。而且可保证状态转换是原子的。
  • 状态对象可被共享。如果State对象没有实例变量——即它们表示的状态完全以它们的类型来编码——那么各Context对象可以共享一个State对象。

缺点

  • 会增加系统类和对象的个数。
  • 对"开闭原则"的支持不太好。增加新的状态类需要修改那些负责状态转换的源代码,而且修改某个状态类的行为也需修改对应类的源代码。

相关模式

  • Flyweight:通过享元模式来实现何时以及怎样共享状态对象。
  • Singleton:状态对象通常是单例。

继续阅读