欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

状态模式——java设计模式(二十二)

程序员文章站 2024-03-23 08:31:52
...

简介

状态模式(State Pattern):允许一个对象在内部状态改变时改变行为,看起来似乎修改了类。

  • 解决复杂对象的状态转换以及不同状态下行为的封装问题。状态模式可以将一个对象的状态提取出来封装到一个类中,使得对象状态变化更加灵活,并且客户端可以不用关心对象的当前状态和状态转换。

结构和实现

  • 角色包括:
    • 环境类:拥有多种状态的对象,维持一个状态对象的引用。
    • 抽象状态类:声明各种状态的方法,并实现子类的相同方法。
    • 具体状态类:实现抽象状态类,对应环境的一个具体状态,行为有所不同。
  • 状态模式结构。
    状态模式——java设计模式(二十二)
  • 状态转换可以由环境类统一负责。新增具体状态需要修改环境类。
public void changeState() {  
    //判断属性值,根据属性值进行状态转换  
     if (value == 0) {  
        this.setState(new ConcreteStateA());  
    }  
    else if (value == 1) {  
        this.setState(new ConcreteStateB());  
    }  
       ......  
}  
  • 状态转换也可以由具体状态类负责。此时,状态类为了获得环境的属性,会依赖或关联环境类。
public void changeState(Context ctx) {  
    //根据环境对象中的属性值进行状态转换  
     if (ctx.getValue() == 1) {  
        ctx.setState(new ConcreteStateB());  
    }  
    else if (ctx.getValue() == 2) {  
        ctx.setState(new ConcreteStateC());  
    }  
       ......  
} 

实例

状态类状态转换

  • 银行账户存在3中状态,需要在其中转换。
    1. 余额>=0,正常,可存款和取款。
    2. -2000<余额<0,透支,可存款和取款,按天计算利息。
    3. 余额=-2000,受限,只能存款,按天计算利息
  • 银行账户状态图。
    状态模式——java设计模式(二十二)
  • 银行账户结构图
    状态模式——java设计模式(二十二)
  • 账户初始为正常状态。
    public Account(String owner,double init) {  
        this.owner = owner;  
        this.balance = balance;  
        this.state = new NormalState(this); //设置初始状态        
    }  
  • 调用存取款的函数之后,进行状态检查,判断是否需要转换状态。
    public void deposit(double amount) {  
        acc.setBalance(acc.getBalance() + amount);  
        stateCheck();  
    }  

环境类状态转换

  • 开发放大镜,点击之后在1、2、4倍大小之间循环。
    状态模式——java设计模式(二十二)

共享状态

  • 对个环境对象需要共享一个或多个状态对象,需要将这个对象定义为环境类的静态变量,以便对象共享。
  • 两个个开关共享开状态和关状态,需要同时开,系统才处于开的状态。
    状态模式——java设计模式(二十二)

优缺点和适用范围

  • 优点:
    • 集中管理状态。状态转换的代码可封装在环境类和具体状态类的方法中,无需分散在业务代码里,使用庞大的条件语句。
    • 易于改变行为。只需要改变具体状态类,可以方便的改变行为。
    • 共享状态对象。减少系统中状态对象的个数。
  • 缺点:
    • 增加类和对象。提取出状态类和对象,增大开销。
    • 结构复杂。状态模式结构和实现复杂,设计难度大。
    • 不完全符合开闭原则。新增状态需要修改负责状态转换的源码,修改状态的行为也需要修改对应类的源码。
  • 适用范围:
    • 对象的行为依赖于状态。
    • 代码中包含大量与对象状态相关的条件语句,使得代码的维护性和灵活性变差。

jdk中的应用

  • Iterator中,根据迭代器的类型,具体操作不同。状态类为Iterator,具体状态类为各种集合的迭代器。
  • 集合类的迭代器
相关标签: 状态