设计模式20之状态模式

背景

在开发过程中,对象会有根据不同的情况做出不同的行为,而影响行为的属性称之为状态属性,这个对象也就是状态对象。

我们在编码时,可能会使用if-else来做状态判断。例如我有一个活动类Activity,这个类里面有一个活动开始字段,活动结束字段,还有一个状态字段,现在我们要来判断活动的状态:未开始、进行中、已结束。示例代码如下:

当状态很多,那么程序会变得很复杂。如果有新的状态增加,就要添加新的if语句,违背设计原则中的开闭原则。

所以我们采用状态模式来解决这个问题,我们将对象状态的判断逻辑抽离出来,放到一个状态类中,这样将原本复杂的逻辑判断简单化。

什么是状态模式

Allow an object to alter its behavior when its internal state changes.The object will appear to change its class.(当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类。)

状态模式由下面3个要素构成:

  • 环境(Context)角色:也称为上下文,它定义了客户感兴趣的接口,维护一个当前状态,并将与状态相关的操作委托给当前状态对象来处理。

  • 抽象状态(State)角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为。

  • 具体状态(Concrete  State)角色:实现抽象状态所对应的行为。

结构图如下:

状态模式

示例代码

State

public abstract class State {
    public abstract void handle(Context context);
}

Context

public class Context {
    private State state;

    //定义环境类的初始状态
    public Context() {
        this.state = new ConcreteStateA();
    }

    //设置新状态
    public void setState(State state) {
        this.state = state;
    }

    //读取状态
    public State getState() {
        return (state);
    }

    //对请求做处理
    public void handle() {
        state.handle(this);
    }
}

ConcreteState

public class ConcreteStateA extends State{
    public void handle(Context context)
    {
        System.out.println("当前状态是 A.");
        context.setState(new ConcreteStateB());
    }
}

public class ConcreteStateB extends State{
    public void handle(Context context)
    {
        System.out.println("当前状态是 B.");
        context.setState(new ConcreteStateA());
    }
}

测试代码

@Test
public void test() {
    Context context=new Context();    //创建环境
    context.handle();    //处理请求
    context.handle();
    context.handle();
    context.handle();
}

测试结果:

当前状态是 A.
当前状态是 B.
当前状态是 A.
当前状态是 B.

我们每调用一次handle(),就改变一次状态。

关于状态模式的思考

经过上面的讲解,你肯定知道状态模式的使用场景了吧。当对象的行为取决于它的状态,并且在运行时会根据他的状态来改变它的行为。我们就可以考虑使用状态模式。

状态模式的好处在于,我可以避免写过多的switch-case或者if-else语句。这样避免了程序的过分复杂。

从上面的代码我们可以知道,开发者无需知道状态的改变细节。这种良好的封装性是我们的代码更优雅。

但是你是否意识到,如果状态类型太多,那么就要写很多的状态子类,这样也会加大系统的管理难度。使用状态模式的时候要考虑这方面的问题。

关于消除if-else,我之前也写过文章使用枚举和策略模式消除,现在又多了一种方法😀。感兴趣的可以看看我之前写的文章:

👉如何用枚举消除if/else?-枚举高阶用法

👉公司系统if-else语句太多了,我用设计模式消除了if-else

这篇文章就写到这里啦,谢谢阅读!

往期推荐

扫码二维码,获取更多精彩。或微信搜Lvshen_9,可后台回复获取资料

  1. 回复"java" 获取java电子书;

  2. 回复"python"获取python电子书;

  3. 回复"算法"获取算法电子书;

  4. 回复"大数据"获取大数据电子书;

  5. 回复"spring"获取SpringBoot的学习视频。

  6. 回复"面试"获取一线大厂面试资料

  7. 回复"进阶之路"获取Java进阶之路的思维导图

  8. 回复"手册"获取阿里巴巴Java开发手册(嵩山终极版)

  9. 回复"总结"获取Java后端面试经验总结PDF版

  10. 回复"Redis"获取Redis命令手册,和Redis专项面试习题(PDF)

  11. 回复"并发导图"获取Java并发编程思维导图(xmind终极版)

另:点击【我的福利】有更多惊喜哦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值