首页 > 其他分享 >设计模式 20 状态模式

设计模式 20 状态模式

时间:2024-09-09 11:52:27浏览次数:13  
标签:状态 20 context 模式 state Context 设计模式 public

设计模式 20

  • 创建型模式(5):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
  • 结构型模式(7):适配器模式、桥接模式、组合模式、装饰者模式、外观模式、享元模式、代理模式
  • 行为型模式(11):责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式

文章目录

状态模式(State Pattern)

1 定义

状态模式的核心思想是将与状态相关的行为封装在独立的状态对象中,并通过状态对象来管理对象的状态转换。这样,原始对象在其状态发生变化时,会自动切换到对应的状态对象,从而表现出不同的行为。

2 结构

状态模式包含以下角色:

  • 上下文(Context): 维护一个当前状态,并在状态发生变化时,切换到新的状态对象。上下文对象向客户端暴露接口,但行为的实现由状态对象负责。
  • 状态接口(State): 定义状态的接口,声明在该状态下对象可以执行的行为。
  • 具体状态(ConcreteState): 实现状态接口,定义该状态下的具体行为。当上下文处于此状态时,行为由具体状态对象执行。

UML 类图

+-------------------+       +-----------------------------------+
|      Context      |       |       State                       |
+-------------------+       +-----------------------------------+
| - state: State    |<------| + Handle(context: Context): void  |
| + Request(): void |       +-----------------------------------+
+-------------------+            ^                     ^
                                 |                     |
                                 |                     |
    +-----------------------------------+        +-----------------------------------+
    | ConcreteStateA                    |        | ConcreteStateB                    |
    +-----------------------------------+        +-----------------------------------+
    | + Handle(context: Context): void  |        | + Handle(context: Context): void  |
    +-----------------------------------+        +-----------------------------------+

3 示例代码

假设我们要实现一个简单的电灯开关系统,电灯可以处于“开”和“关”两种状态,并且根据当前的状态来执行不同的操作。

状态接口

// 状态接口
public interface IState
{
    void Handle(Context context);
}

具体状态类

// 具体状态 - 开灯状态
public class OnState : IState
{
    public void Handle(Context context)
    {
        Console.WriteLine("The light is already ON.");
        context.SetState(new OffState());
    }
}

// 具体状态 - 关灯状态
public class OffState : IState
{
    public void Handle(Context context)
    {
        Console.WriteLine("The light is OFF. Turning it ON.");
        context.SetState(new OnState());
    }
}

上下文类

// 上下文类
public class Context
{
    private IState _state;

    public Context(IState state)
    {
        _state = state;
    }

    public void SetState(IState state)
    {
        _state = state;
    }

    public void Request()
    {
        _state.Handle(this);
    }
}

客户端代码

class Program
{
    static void Main(string[] args)
    {
        Context context = new Context(new OffState());

        // 初始状态为关灯状态
        context.Request(); // 关灯 -> 开灯

        // 再次请求
        context.Request(); // 开灯 -> 关灯

        // 再次请求
        context.Request(); // 关灯 -> 开灯
    }
}

运行结果

The light is OFF. Turning it ON.
The light is already ON.
The light is OFF. Turning it ON.

在这个例子中,Context 类维护一个当前状态,当调用 Request() 方法时,会根据当前状态执行相应的操作并切换到下一个状态。OnStateOffState 是两种具体的状态类,分别定义了在不同状态下的行为。

6 特点

  • 优点:

    • 减少复杂性: 通过将状态相关的行为封装在独立的状态对象中,状态模式消除了大量的条件分支语句,使代码更加清晰和易于维护。

    • 状态转换灵活: 可以很容易地添加、删除或修改状态对象,扩展系统的功能,而无需修改上下文类。

    • 符合单一职责原则: 状态模式将与状态相关的行为封装在不同的状态类中,使得每个类只负责一种状态的行为,简化了代码的管理。

  • 缺点:

    • 增加类的数量: 每个状态都需要定义一个具体的状态类,当状态过多时,可能会导致类的数量急剧增加,增加系统的复杂性。

    • 状态之间的依赖: 如果状态之间存在复杂的依赖关系,可能会导致状态之间的转换逻辑变得复杂,难以维护。

7 适用场景

  • 对象的行为依赖于其状态: 当一个对象的行为依赖于其状态,并且它的状态会在运行时改变时,状态模式非常适用。
  • 状态逻辑复杂: 当状态转换的逻辑非常复杂,或者状态之间的转换规则经常变化时,状态模式能够有效地管理这些逻辑。
  • 消除条件分支: 如果代码中存在大量的条件分支语句来处理不同的状态,状态模式可以通过将状态逻辑分散到不同的状态类中来简化代码。

8 总结

状态模式通过将状态相关的行为封装在独立的状态对象中,简化了对象的状态管理逻辑。它消除了大量的条件分支语句,使代码更加清晰和易于扩展。尽管状态模式可能会增加类的数量,但它为管理复杂的状态转换逻辑提供了一种灵活且有效的解决方案。

标签:状态,20,context,模式,state,Context,设计模式,public
From: https://blog.csdn.net/szy13323042191/article/details/142055379

相关文章

  • 设计模式 21 策略模式
    设计模式21创建型模式(5):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式结构型模式(7):适配器模式、桥接模式、组合模式、装饰者模式、外观模式、享元模式、代理模式行为型模式(11):责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者......
  • BaseCTF2024-week3-Crypto部分题目wp
    先放一下官方的wp(我这里只放我出的题):https://j0zr0js7k7j.feishu.cn/wiki/XN3BwnHrZihQ3ZkhEyocb5EJnUd没有n啊fromCrypto.Util.numberimport*importgmpy2flag=b'BaseCTF{}'m=bytes_to_long(flag)p=getPrime(512)q=getPrime(512)n=p*qe=65537phi=(p-1)*(q-1)d......
  • 如何在Spark键值对数据中,对指定的Key进行输出/筛选/模式匹配
    在用键值对RDD进行操作时,经常会遇到不知道如何筛选出想要数据的情况,这里提供了一些解决方法目录1、对固定的Key数据进行查询2、对不固定的Key数据进行模糊查询1、对固定的Key数据进行查询代码说明:SparkConf:配置Spark应用程序的一些基本信息。SparkContext:创建Spark......
  • 题解 GZOI2023D2B【乒乓球】
    4s,512M题目描述Alice和Bob在打乒乓球,乒乓球比赛的规则是这样的:一场比赛中两位选手将进行若干局比赛,选手只需要赢得\(X\)局比赛就宣告其胜利;每局比赛中两位选手将进行若干盘比赛,选手只需要赢得\(Y\)盘比赛就宣告其胜利;每盘比赛中两位选手将进行乒乓球对决,有且仅有一位选......
  • LivePortrait: 让静态图像“活”起来、更好地控制图片/视频中人物的表情,新增动物模式,
     引言随着AI技术的飞速发展,图像生成与编辑的门槛不断降低,尤其在人像视频生成领域取得了令人瞩目的成就。快手可灵大模型团队开源的LivePortrait框架,以其出色的性能与创新的设计,引领了AI生成的新浪潮。LivePortrait不仅能够将静态图像转换为动态视频,还能精确控制面......
  • 【优技教育】Oracle 19c OCP 082题库(第16题)- 2024年修正版
    【优技教育】Oracle19cOCP082题库(Q16题)-2024年修正版考试科目:1Z0-082考试题量:90通过分数:60%考试时间:150min本文为(CUUG原创)整理并解析,转发请注明出处,禁止抄袭及未经注明出处的转载。原文地址:http://www.cuug.com/index.php?s=/home/article/detail/id/3397.html第......
  • day20打卡
    复原IP地址classSolution{public:boolisValid(strings,intstart,intend){if(start>end){returnfalse;}if(s[start]=='0'&&start!=end){//0开头的数字不合法returnfalse;}intnum=0;for(inti=start;i<=end;i++){i......
  • 【2024-09-08】连岳摘抄
    23:59真正的爱,其价值在于始终如一的行动,这远远大于转瞬即逝的感觉或精神贯注。真正的爱出自自我意愿,只能依靠实际行动来证明。“爱与“非爱”的区别,正如善与恶的区别一样,有着客观的标准。爱是行动,不是空想。                      ......
  • 整车低压电源模式介绍
    引言  在日新月异的汽车行业中,有老牌车企不断推出新品牌,也出现了许多新势力车企。在这种市场环境下,各个车型的功能及其实现方式会存在许多的差异。本篇文章主要给大家介绍的是低压电源模式,希望能对大家有所帮助。  一、电源模式概述  整车低压电源模式是指整车上电......
  • 【2024-09-07】连岳摘抄
    23:59白露团甘子,清晨散马蹄。圃开连石树,船渡入江溪。凭几看鱼乐,回鞭急鸟栖。渐知秋实美,幽径恐多蹊。                                              ——《白露》唐·杜甫你......