首页 > 其他分享 >行为型设计模式之状态模式

行为型设计模式之状态模式

时间:2022-09-27 22:08:53浏览次数:45  
标签:状态 STATE 模式 State context 设计模式 行为 public

状态模式

状态模式(State Pattern)属于行为型模式。它是允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类。

状态模式中类的行为是由状态决定的,不同的状态下有不同的行为。其意图是让一个对象在其内部改变的时候,其行为也随之改变。状态模式核心是状态与行为绑定,不同的状态对应不同的行为。

状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况。通过把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化。对象的行为依赖于它的状态属性,并且会根据它的状态改变而改变它的相关行为。

应用场景

1.行为随状态改变而改变的场景

2.一个操作中含有庞大的多分支结构,并且这些分支取决于对象的状态。

例如:订单信息的变化、快递信息的变化、文档的审核状态变化。

假如有一个 文档Doc­u­ment类。 文档可能会处于草稿Draft 、审阅中Mod­er­a­tion和已发布Pub­lished三种状态中的一种。 文档的pub­lish发布方法在不同状态下的行为略有不同:

草稿状态时, 它会将文档转移到审阅中状态。

审阅中状态时, 如果当前用户是管理员, 它会公开发布文档。

已发布状态时, 它不会进行任何操作。

在这里插入图片描述

优缺点

优点:

1.结构清晰:将状态独立为类,封装转换规则。消除冗余的if.else或switch...case语句,使代码更加简洁,提高系统可维护性。

2.将状态转换显示化:通常对象内部都是使用数值类型来定义状态,状态的切换是通过赋值进行表现,不够直观。而使用状态类,在切换状态时,是以不同的类进行表示,转换目的更加明确。

3.将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为。

缺点:

1.类膨胀:如果一个事物具备很多状态,必然会增加系统类和对象的个数,会造成状态类太多

2.状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱

3.状态模式对开闭原则的支持并不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态,而且修改某个状态类的行为也需修改对应源码。

主要角色

1.环境类角色(Context)

定义客户端需要的接口,内部维护一个当前状态实例,并负责具体状态的切换。

2.抽象状态角色(Sate)

定义该状态下的行为,可以有一个或多个行为。

3.具体状态角色(ConcreteState)

具体实现该状态对应的行为,并且在需要的情况下进行状态切换。

在这里插入图片描述

状态模式的基本使用

创建抽象状态角色

抽象状态角色,定义该状态下的行为,可以有一个或多个行为

public abstract class State {
    protected Context context;

    public void setContext(Context context) {
        this.context = context;
    }
    /**
     * 一个行为
     */
    public abstract void action();
}

创建具体状态角色

创建具体状态角色,具体实现该状态对应的行为,并且在需要的情况下进行状态切换

public class ConcreteStateA extends State {
    @Override
    public void action() {
        if (Math.random() > 0.5) {
            System.out.println("ConcreteStateA执行成功,继续执行!");
            // 行为状态自动切换
            this.context.setState(Context.STATE_B);
            this.context.getState().action();
        } else {
            System.out.println("ConcreteStateA执行完成");
        }
    }
}
public class ConcreteStateB extends State {
    @Override
    public void action() {
        if (Math.random() > 0.5) {
            System.out.println("ConcreteStateB执行成功,继续执行!");
            // 行为状态自动切换
            this.context.setState(Context.STATE_C);
            this.context.getState().action();
        } else {
            System.out.println("ConcreteStateB执行完成");
        }
    }
}
public class ConcreteStateC extends State {
    @Override
    public void action() {
        System.out.println("ConcreteStateC执行完成");
    }
}

创建环境类角色

创建环境类角色,定义客户端需要的接口,内部维护一个当前状态实例,并负责具体状态的切换。

public class Context {
    public static final State STATE_A = new ConcreteStateA();
    public static final State STATE_B = new ConcreteStateB();
    public static final State STATE_C = new ConcreteStateC();

    /**
     * 默认状态
     */
    private State defaultState = STATE_A;

    {
        STATE_A.setContext(this);
        STATE_B.setContext(this);
        STATE_C.setContext(this);
    }

    public void setState(State state) {
        this.defaultState = state;
        this.defaultState.setContext(this);
    }

    public State getState() {
        return this.defaultState;
    }

    public void doAction() {
        this.defaultState.action();
    }
}

客户端执行

    public static void main(String[] args) {
        System.out.println("---------从状态A开始执行---------");
        Context context = new Context();
        context.doAction();

        System.out.println("---------从状态B开始执行---------");
        context.setState(new ConcreteStateB());
        context.doAction();
    }
---------从状态A开始执行---------
ConcreteStateA执行成功,继续执行!
ConcreteStateB执行成功,继续执行!
ConcreteStateC执行完成
---------从状态B开始执行---------
ConcreteStateB执行成功,继续执行!
ConcreteStateC执行完成

标签:状态,STATE,模式,State,context,设计模式,行为,public
From: https://blog.51cto.com/chencoding/5711157

相关文章

  • GB/T28181-2016 SDP定义和音视频传输模式解读
     SDP定义联网系统中SIP消息体中携带的SDP内容应符合IETFRFC2327的相关要求。应有如下字段:Sessiondescription:v=(protocolversion)o=(owner/creatorandsessioni......
  • 编码中的Adapter,不仅是一种设计模式,更是一种架构理念与解决方案
    大家好,又见面了。不知道下面这玩意大家有没有见过或者使用过?这是一个插座转换器。我们都知道日常使用的是220v的交流电,而国外不同国家使用的电流电压是不一样的(比如日本使......
  • JAVA设计模式-原型模式
    JAVA设计模式-原型模式介绍原型模式是一种创建型模式,用于创建重复的对象,并且保证性能。原型模式创建的对象是由原型对象自身创建的,是原型对象的一个克隆,和原型对象具有......
  • 构建器模式 Builder
    “对象创建”模式通过“对象创建”模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定。它是接口抽象之后的第一步工作。典型模式......
  • 基于blackbox_exporter实现对URL状态、IP可用性、端口状态、TLS证书的过期时间监控
    一、blackbox_exporter介绍blackbox_exporter是Prometheus官方提供的一个exporter,可以监控HTTP、HTTPS,、DNS、TCP、ICMP等目标实例,从而实现对被监控节点进行......
  • 03-Go设计模式-工厂方法模式
    工厂模式方法模式示例代码/*工厂方法模式抽象工厂(AbstractFactory)角色:工厂方法模式的核心,任何工厂类都必须实现这个接口工厂(ConcreteFactory)角色:具体工厂类是抽象工......
  • 02-Go设计模式-简单工厂
    简单工厂模式示例代码/*简单工厂模式角色和职责工厂(Factory)角色:简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象......
  • Envoy 有状态会话保持机制设计与实现
    Envoy有状态会话保持机制设计与实现1问题背景会话保持是七层负载均衡的核心功能之一。对于同一会话的请求或者连接,通过会话保持机制,负载均衡软件会将其路由到同一个后......
  • 组合模式
    组合模式职务接口packagecompositetypejobberinterface{ setJob(string) setManager(jobber) addSubordinate(jobber) print(string)}职务节点packagecom......
  • 设计模式 -- Prototype(原型模式)
    原型模式(Prototype)使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。在软件系统中,经常面临着“某些结构复杂的对象”的创建工作;由于需求的变化,这些......