首页 > 其他分享 >设计模式-状态模式(State pat)

设计模式-状态模式(State pat)

时间:2024-07-23 15:20:05浏览次数:8  
标签:状态 pat context state State Context 设计模式 public

设计模式-策略模式(State Pattern)

   概要

   记忆关键词:状态变成类

   定义:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

   状态模式结构图如下:

   

   一、能解决什么问题 ?

   它主要用来解决对象在多种状态转换时,需要对外输出不同行为的问题。状态和行为是一一对应的,状态之间可以相互转换。当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类。例如:淘宝下单,订单有待付款,已付款待发货,待收货,待评价, 已完成等状态。每个状态对应的行为都是不同的, 一个状态完成会流转到下一个状态。

   通常对有状态的对象进行编程,我们的解决方案是:思考可能存在的所有状态,然后使用 if-else 或 switch-case 语句来进行状态判断,然后再根据不同的状态进行不同的处理。如上面的案例--淘宝下单:

public class ClientApplication {
    public static void main(String[] args) {
        String status = "待付款";
        if ("待付款".equals(status)) {
            // 执行付款逻辑
        } else if("待发货".equals(status)) {
            // 执行发货逻辑
        } else if("待收货".equals(status)) {
            // 执行收货逻辑
        } else if("待评价".equals(status)) {
            // 执行评价逻辑
        } else if("待收货".equals(status)) {
            // 执行收获逻辑
        }
    }
}

   大量的if...else的缺点很明显:

  •    违背开闭原则: 当增加一种状态的时候, 需要修改原来的逻辑。
  •    当状态很多的时候, 代码段很长, 臃肿, 不容易维护, 可扩展性差。

    二、涉及的角色

    1. State 抽象状态类

    定义一个接口以封装与Context的一个特定状态相关的行为

    代码示例如下:    

1 public interface State {
2 
3     /**
4      * 处理状态
5      *
6      * @param context 状态
7      */
8     void handleState(Context context);
9 }

    2. ConcreteState(具体状态实现类)

    具体状态实现类,每一个子类实现一个与Context的一个状态相关的行为

    代码示例如下:

    具体实现类一:

1 public class ConcreteState1 implements State{
2     @Override
3     public void handleState(Context context) {
4         System.out.println("Handling state 1");
5         // 在这里执行与状态1相关的行为
6         // 可能会改变上下文的状态
7         context.setState(new ConcreteState2());
8     }
9 }

      具体实现类二:

1 public class ConcreteState2 implements State{
2     @Override
3     public void handleState(Context context) {
4         System.out.println("Handling state 2");
5         // 在这里执行与状态2相关的行为
6         // 可能会改变上下文的状态
7         context.setState(new ConcreteState1());
8     }
9 }

    3. Context(上下文环境类)

    维护一个ConcreteState子类的实例,这个实例定义当前的状态

    代码示例如下:

 1 public class Context {
 2 
 3     /**
 4      * 在环境类中维护一个抽象状态State的实例, 这个实例存储当前状态。
 5      */
 6     private State state;
 7 
 8     public Context() {
 9         this.state = new ConcreteState1();
10     }
11 
12     public void setState(State state) {
13         this.state = state;
14     }
15 
16     public State getState() {
17         return state;
18     }
19 
20     /**
21      * 在环境类中定义所有状态执行的方法.
22      */
23     public void request() {
24         // 委托给具体状态类处理
25         state.handleState(this);
26     }
27 }

  客户端调用:

 1 public class Client {
 2     public static void main(String[] args) {
 3         Context context = new Context();
 4         context.request();
 5         System.out.println("当前状态为:" + context.getState());
 6 
 7         // 连续请求,观察状态的变化
 8         context.request();
 9         System.out.println("当前状态为:" + context.getState());
10 
11         // 连续请求,观察状态的变化
12         context.request();
13         System.out.println("当前状态为:" + context.getState());
14     }
15 }
16 
17 
18 //运行结果:
19 Handling state 1
20 当前状态为:org.example.state.ConcreteState2@7d4991ad
21 Handling state 2
22 当前状态为:org.example.state.ConcreteState1@28d93b30
23 Handling state 1
24 当前状态为:org.example.state.ConcreteState2@1b6d3586

   三、算法分析

   1. 状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况

   把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。当然,如果这个状态判断很简单,那就没必要用状态模式了。

   2. 帮助对象通过改变它们内部的状态来控制其行为

   3. 当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。

   四、状态模式与策略模式的区别

   1. 状态模式和策略模式的 UML 一样,但是解决的问题和侧重不一样

   2. 状态模式重点在各状态之间的切换从而做不同的事情,而策略模式更侧重于根据具体情况选择策略,并不涉及切换

   3. 状态模式不同状态下做的事情不同,而策略模式做的都是同一件事

   4. 状态模式封装了对象的状态,而策略模式封装算法或策略。因为状态是跟对象密切相关的,它不能被重用;而通过从Context中分离出策略或算法,我们可以重用它们

   5. 在状态模式中,每个状态通过持有Context的引用,来实现状态转移;但是每个策略都不持有Context的引用,它们只是被Context使用。

 

   参考链接:

   https://www.cnblogs.com/ITPower/p/14980134.html

标签:状态,pat,context,state,State,Context,设计模式,public
From: https://www.cnblogs.com/hld123/p/18318493

相关文章

  • 【Java常用设计模式】通俗易懂的玩转单例、建造者、工厂、策略模式(保姆篇)
    文章目录单例模式建造者模式工厂模式策略模式本篇小结更多相关内容可查看在一个狂风骤雨的下午,有人突然问了我一句,单例模式是什么,我愣了,相信看完这篇就不会愣了,本文以通俗易懂的方式写的,可能有不严谨的地方......
  • Xpath 高级用法
    ○定位某元素同级元素的上一个 preceding-sibling::    ○(//li[@class="el-iconmorebtn-quickprevel-icon-more"]/preceding-sibling::li)[last()]   ○定位某元素同级元素的下一个following-sibling::    ○//li[@class="el-iconmorebtn-q......
  • 类型错误:需要 str、bytes 或 os.PathLike 对象,而不是 _io.BufferedReader
    我正在尝试迭代本地计算机上文件夹中的一组文件,并使用此代码(Python3.6.132位、Windows1064位)仅将文件名包含“Service_Areas”的文件上传到我的FTP站点):ftp=FTP('ftp.ftpsite.org')username=('username')password=('password')ftp.login(username,password)......
  • AWS Elastic Beanstalk chown PythonPath 错误
    我正在AWS的elasticbeanstalk上部署一个Web应用程序,遇到了同样的错误:[StageApplication].Stoprunningthecommand.Error:chown/var/app/staging/venv/bin/python:nosuchfileordirectory.我在我的环境配置中看到属性:PYTHONPATH:/var/......
  • 生产者消费者设计模式
    生产者消费者设计模式学习一、什么是生产者消费者设计模式Java中的生产者-消费者设计模式是一种用于多线程编程的经典设计模式,它用于解决多个线程之间共享资源时的同步和通信问题。这个模式主要用在有数据生产者(Producer)和数据消费者(Consumer)的场景中,生产者负责产生数据,而消费者......
  • kubernetes核心概念 Controller控制器之StatefulSet
    Kubernetes核心概念Controller之StatefulSet控制器一、StatefulSet控制器作用StatefulSet是用来管理有状态应用的控制器。StatefulSet用来管理某Pod集合的部署和扩缩,并为这些Pod提供持久存储和持久标识符。参考:https://kubernetes.io/zh/docs/concepts/workl......
  • 职责链、命令和观察者设计模式的区别
    职责链、命令和观察者是三种不同的设计模式,它们各自解决不同类型的问题。下面分别介绍这三种设计模式的特点和区别:1.职责链模式(ChainofResponsibility)定义:职责链模式是一种行为设计模式,它通过将请求的处理者组织成一个链,使得请求可以沿这条链传递,直到有一个处理者处理......
  • SLF4J: Class path contains multiple SLF4J bindings 问题解决
    背景:springboot项目名称test,在使用slf4j后,服务启动报错 报错信息:SLF4J:ClasspathcontainsmultipleSLF4Jbindings.SLF4J:Foundbindingin[jar:file:/D:/Program%20Files/Java/.m2/repository/ch/qos/logback/logback-classic/1.2.7/logback-classic-1.2.7.jar!/or......
  • 路由追踪以及常用命令tracert\pathping
    一、常用的命令:对于网络工程师来说,需要熟练掌握的Windows路由追踪命令有两个:tracert和pathping,其中pathping是tracert和ping命令的结合,不但可以追踪目标IP地址的路由,还可以测试经过的每一跳的时延和丢包率。1.1tracert命令及举例tracert命令,通过向目标IP地址发送不同T......
  • office365.sharepoint 中的 moveto 或 move_to_using_path 是否处于活动状态?
    我正在尝试使用Office365-REST-Python-Client中的示例将文件从一个文件夹移动到另一个文件夹,但它不起作用:fromoffice365.sharepoint.client_contextimportClientContextfromoffice365.sharepoint.files.move_operationsimportMoveOperationsfromtestsimporttest_t......