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

简介

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

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

结构和实现

  • 角色包括:
    • 环境类:拥有多种状态的对象,维持一个状态对象的引用。
    • 抽象状态类:声明各种状态的方法,并实现子类的相同方法。
    • 具体状态类:实现抽象状态类,对应环境的一个具体状态,行为有所不同。
  • 状态模式结构。
    180515.state.png
  • 状态转换可以由环境类统一负责。新增具体状态需要修改环境类。
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,受限,只能存款,按天计算利息
  • 银行账户状态图。
    180515.bankstate.png
  • 银行账户结构图
    180515.banck.png
  • 账户初始为正常状态。
    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倍大小之间循环。
    180515.sharestate.png

共享状态

  • 对个环境对象需要共享一个或多个状态对象,需要将这个对象定义为环境类的静态变量,以便对象共享。
  • 两个个开关共享开状态和关状态,需要同时开,系统才处于开的状态。
    180515.context.png

优缺点和适用范围

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

jdk中的应用

  • Iterator中,根据迭代器的类型,具体操作不同。状态类为Iterator,具体状态类为各种集合的迭代器。
  • 集合类的迭代器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值