前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式20之状态模式

设计模式20之状态模式

作者头像
Lvshen
发布2022-05-05 18:24:44
2240
发布2022-05-05 18:24:44
举报

背景

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

我们在编码时,可能会使用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

代码语言:javascript
复制
public abstract class State {
    public abstract void handle(Context context);
}

Context

代码语言:javascript
复制
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

代码语言:javascript
复制
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());
    }
}

测试代码

代码语言:javascript
复制
@Test
public void test() {
    Context context=new Context();    //创建环境
    context.handle();    //处理请求
    context.handle();
    context.handle();
    context.handle();
}

测试结果:

代码语言:javascript
复制
当前状态是 A.
当前状态是 B.
当前状态是 A.
当前状态是 B.

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

关于状态模式的思考

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

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

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

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

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

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-11-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Lvshen的技术小屋 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 什么是状态模式
  • 示例代码
    • State
      • Context
        • ConcreteState
          • 测试代码
          • 关于状态模式的思考
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档