设计模式:状态模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)

news2024/10/6 6:00:39

上一篇《备忘录模式》                                                        下一篇《访问者模式》

简介:

状态模式,它是一种对象行为型模式,它允许一个对象在其内部状态改变时改变它的行为。这种模式可以让一个对象的行为随着状态的改变而改变,增强了代码的可维护性和灵活性。

在状态模式中,通常有一个状态的接口,以及一些具体状态类。这些具体状态类实现了状态的接口,并定义了在该状态下对象的行为。上下文类则包含一个状态对象,并定义了如何改变状态的方法。在上下文类中,根据当前状态和请求,可以调用当前状态的 Handle 方法来处理请求,并更新状态。

状态模式的使用场景:
1、一个对象存在多个状态,状态可以相互转换。
2、不同状态下,行为不同。
3、代码中包含大量与对象状态有关的 if/else 或 switch case 语句,且这些条件执行与否依赖于该对象的状态。

状态模式的创建步骤:
1、创建一个接口,表示状态的抽象。
2、创建实现接口的实体类,表示具体状态。
3、创建一个上下文类,包含一个状态对象,并定义如何改变状态的方法。
4、在上下文类中,根据当前状态和请求,调用当前状态的 Handle 方法来处理请求,并更新状态。

以上是状态模式的基本创建步骤,您可以根据实际应用场景进行调整和扩展。

状态模式的优点,主要包括:
1、封装了状态的转换规则,将状态的转换代码封装在环境类或者具体状态类中,集中管理状态转换代码,而不是分散在一个个业务方法中。
2、将所有与某个状态有关的行为放到一个类中,只需要注入一个不同的状态对象即可使环境对象拥有不同的行为。
3、允许状态转换逻辑与状态对象合成一体,而不是提供一个巨大的条件语句块,从而避免将业务方法和状态转换代码交织在一起。
4、可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数。

状态模式的缺点,主要包括:
1、类膨胀:如果一个事物具备很多状态,则会造成状态类太多,导致系统复杂度增加。
2、状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。
3、状态模式对开闭原则的支持不太好,对于可以切换状态的状态模式,增加新的状态类需要修改那些负责状态转换的源代码,否则无法切换到新增状态。
4、如果状态数量比较多,状态类的数量会增加,业务场景系统变得很复杂。


示例:

一、C#状态模式

以下是一个示例,展示了如何在C#中实现状态模式:

//首先定义一个状态的接口:
public interface State  
{  
    void Handle(Context context);  
}
//然后定义一些具体的状态:
public class StateA : State  
{  
    public void Handle(Context context)  
    {  
        Console.WriteLine("State A handled. Switching to State B");  
        context.State = new StateB();  
    }  
}  
  
public class StateB : State  
{  
    public void Handle(Context context)  
    {  
        Console.WriteLine("State B handled. Switching to State A");  
        context.State = new StateA();  
    }  
}
//然后定义一个上下文(Context)类,它包含一个状态对象,并定义如何改变状态的方法:
public class Context  
{  
    private State _state;  
    public Context(State state)  
    {  
        this._state = state;  
    }  
    public State State { get { return _state; } }  
    public void Request() => _state.Handle(this);  
}
//最后在主函数中使用:
public static void Main(string[] args)  
{  
    var stateA = new StateA();  
    var context = new Context(stateA);  
    context.Request(); 
}

二、java状态模式

状态模式通常通过以下方式实现:

//首先定义一个状态的接口:
public interface State {  
    void handle(Context context);  
}
//然后定义一些具体的状态:
public class StateA implements State {  
    @Override  
    public void handle(Context context) {  
        System.out.println("State A handled. Switching to State B");  
        context.setState(new StateB());  
    }  
}  
  
public class StateB implements State {  
    @Override  
    public void handle(Context context) {  
        System.out.println("State B handled. Switching to State A");  
        context.setState(new StateA());  
    }  
}
//然后定义一个上下文(Context)类,它包含一个状态对象,并定义如何改变状态的方法:
public class Context {  
    private State state;  
  
    public Context(State state) {  
        this.state = state;  
    }  
  
    public void request() {  
        state.handle(this);  
    }  
  
    public void setState(State state) {  
        this.state = state;  
    }  
}
//最后在主函数中使用:
public static void main(String[] args) {  
    StateA stateA = new StateA();  
    Context context = new Context(stateA);  
    context.request(); 
}

三、javascript状态模式

在JavaScript中,状态实现方式如下:

class Context {  
  constructor(state) {  
    this.state = state;  
  }  
  
  request() {  
    this.state.handle(this);  
  }  
}  
  
class State {  
  handle(context) {  
    console.log("Default state handled");  
  }  
}  
  
class StateA extends State {  
  handle(context) {  
    console.log("State A handled. Switching to State B");  
    context.state = new StateB();  
  }  
}  
  
class StateB extends State {  
  handle(context) {  
    console.log("State B handled. Switching to State A");  
    context.state = new StateA();  
  }  
}  
  
const stateA = new StateA();  
const context = new Context(stateA);  
context.request(); 

四、C++状态模式

以下是在C++中实现状态模式:

#include <iostream>  
#include <string>  
  
class Context {  
public:  
    void Request() {  
        m_state->Handle(this);  
    }  
  
private:  
    State* m_state;  
};  
  
class State {  
public:  
    virtual void Handle(Context* context) = 0;  
};  
  
class StateA : public State {  
public:  
    void Handle(Context* context) override {  
        std::cout << "State A handled. Switching to State B" << std::endl;  
        context->m_state = new StateB();  
    }  
};  
  
class StateB : public State {  
public:  
    void Handle(Context* context) override {  
        std::cout << "State B handled. Switching to State A" << std::endl;  
        context->m_state = new StateA();  
    }  
};  
  
int main() {  
    StateA* stateA = new StateA();  
    Context context(stateA);  
    context.Request(); 
}

五、python状态模式

以下是在python中实现状态模式:

from abc import ABC, abstractmethod  
  
class Context(ABC):  
    @abstractmethod  
    def Request(self):  
        pass  
  
class State(ABC):  
    @abstractmethod  
    def Handle(self, context):  
        pass  
  
class StateA(State):  
    def Handle(self, context):  
        print("State A handled. Switching to State B")  
        context.State = StateB()  
  
class StateB(State):  
    def Handle(self, context):  
        print("State B handled. Switching to State A")  
        context.State = StateA()  
  
class Context(Context):  
    def __init__(self, state):  
        self.State = state  
      
    def Request(self):  
        self.State.Handle(self)

六、go状态模式

以下是一个示例,展示了如何在go中实现状态模式:

// State 接口定义了每个状态必须实现的方法  
type State interface {  
 Handle(context *Context)  
}  
  
// ConcreteStateA 是 State 接口的具体实现  
type ConcreteStateA struct{}  
  
func (s *ConcreteStateA) Handle(context *Context) {  
 fmt.Println("State A handled. Switching to State B")  
 context.State = &ConcreteStateB{}  
}  
  
// ConcreteStateB 是 State 接口的具体实现  
type ConcreteStateB struct{}  
  
func (s *ConcreteStateB) Handle(context *Context) {  
 fmt.Println("State B handled. Switching to State A")  
 context.State = &ConcreteStateA{}  
}  
  
// Context 是包含状态的对象的结构体  
type Context struct {  
 State State  
}  
  
func (c *Context) Request() {  
 c.State.Handle(c)  
}

七、PHP状态模式

以下是一个示例,展示了如何在PHP中实现状态模式:

<?php  
interface State {  
    public function handle();  
}  
  
class ConcreteStateA implements State {  
    public function handle() {  
        echo "State A handled. Switching to State B\n";  
        $this->context->setState(new ConcreteStateB());  
    }  
}  
  
class ConcreteStateB implements State {  
    public function handle() {  
        echo "State B handled. Switching to State A\n";  
        $this->context->setState(new ConcreteStateA());  
    }  
}  
  
class Context {  
    private $state;  
  
    public function setState(State $state) {  
        $this->state = $state;  
    }  
  
    public function request() {  
        $this->state->handle();  
    }  
}  
  
// 使用状态模式示例代码:  
$context = new Context();  
$context->setState(new ConcreteStateA()); 


《完结》

上一篇《备忘录模式》                                                             下一篇《访问者模式》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1139241.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker安装及镜像源修改

Docker安装及镜像源修改 一、docker安装1、yum 包更新到最新2、安装需要的软件包&#xff0c; yum-util 提供yum-config-manager功能&#xff0c;另外两个是devicemapper驱动依赖的3、 设置yum源4、 安装docker&#xff0c;出现输入的界面都按 y5、 查看docker版本&#xff0c;…

2023年中国商用洗碗机产量、需求量、市场规模及行业前景分析[图]

商用洗碗机是餐厅、食堂、中央厨房、酒店等应用场景中不可或缺的洁净消毒设备。商用洗碗机一般用于商用目的&#xff0c;随着消费者对食品卫生日渐重视&#xff0c;中国商用洗碗机市场得到了快速发展。商用洗碗机分类洗碗机有多种形式按洗涤方式分&#xff0c;有喷淋式、叶轮式…

AI 数字人短视频变现及引流,轻松掌握流量密码

项目介绍 AI 数字人短视频就是利用 AI 数字人工具 &#xff0c;生成模仿真人的口播视频 &#xff0c;进行涨粉变现。常见的领域有情感 、 创业 、 育儿 、 书单等 &#xff0c;同一个视频可以发布到各大平台 &#xff0c;实现一 鱼多吃。 创业就卖思维类书籍 &#xff0c;育儿…

Android setText()错误

android.content.res.Resources$NotFoundException: String resource ID #0x0at android.content.res.Resources.getText(Resources.java:415)at android.widget.TextView.setText(TextView.java:6375) 出现场景&#xff1a;在RecycleView的 Override public void onBindViewHo…

MySQL数据库#6

Python操作mysql 在使用Python连接mysql之前我们需要先下载一个第三方的模块 pymysql的模块&#xff0c;导入后再进行操作。 操作步骤&#xff1a;1. 先连接mysql host&#xff0c;port&#xff0c;charset&#xff0c;username password 库&#xff0c;等等。 import pymysql…

RawNet 1-3 介绍

1. Overview RawNet: Advanced end-to-end deep neural network using raw waveforms for text-independent speaker verification &#xff08;RawNet 1&#xff09; 出自会议&#xff1a;INTERSPEECH 2019. &#xff08;论文链接&#xff1a;https://arxiv.org/pdf/1904.0…

超分辨率——SESR网络训练并推理测试(详细图文教程)

最近学了一个超轻量化的超分辨率网络SESR&#xff0c;效果还不错。 目录 一、 源码包二、 数据集的准备2.1 官网下载2.2 网盘下载 三、 训练环境配置四、训练4.1 修改配置参数4.2 导入数据集4.3 2倍超分网络训练4.3.1 训练SESR-M5网络4.3.2 训练SESR-M5网络4.3.3 训练SESR-M11…

使用pycharm远程调试

使用pycharm 专业版&#xff0c; 在设置解释器中&#xff0c;具备ssh 解释器功能&#xff1b; 一般在本地无法调试远程端代码&#xff0c;机械性的scp传输文件十分影响工作效率&#xff0c;PyCharm的Pro支持远程Run&#xff0c;Debug&#xff0c;等可视化的功能。 操作系统&…

超声波原理的便携式明渠流量计

便携式明渠流量计是一款便携式的可随带随走的一款仪器&#xff0c;主要是用来和在线明渠流量计做液位和流量比对的一款比对装置。 仪器可自动每两分钟记录一次液位数据&#xff0c;连续记录6次&#xff0c;同时可以累计测量10分钟的流量数据&#xff0c;将其结果与现场在线明渠…

Angular改变组件中样式(两种方法)

项目中遇到修改组件样式的情况&#xff0c;搜了半天资料基本只有vue和react的方法&#xff0c;什么/deep/,v-deep统统不起效&#xff0c;崩溃&#xff01; 所以这里总结一下Angular的方法。 angular中想引入组件并修改组件内样式&#xff0c;有两种方法。 文章目录 方法1&…

壹牛NFT数字艺术藏品数藏开源无加密

这个版本新增了不少功能&#xff0c;也修复了一些地方。 1.平台新增用户找回密码功能 2.平台新增短信注册&#xff08;实名制功能&#xff09; 3.平台新增主图后台添加功能 4.平台修复相关问题&#xff0c;系统高效运行 1、H5端与APP端在新UI完美适配 2、加入宝盒功能&am…

FL Studio21.2最新订阅版本更新升级(详细功能介绍)

好消息&#xff01;FL Studio 21.2 在 10 月 26 日正式发布啦&#xff0c;它新增了 FL Cloud 在线采样库和 AI 音乐制作功能&#xff0c;还提供音乐分发到 Spotify、Apple Music 等主要音乐平台的服务。此外&#xff0c;还有新的音频分离功能、自定义波形颜色和新的合成器 Kepl…

下一代金融将呈现 7 项激动人心的金融科技创新

金融科技处于现代技术发展的前沿。随着金融科技领域价值超过 1790 亿美元&#xff0c;初创企业和创新者都在寻找金融和银行业的下一个重大事件。 本文讨论了 2024 年的 7 项金融科技创新。 其中一些创新建立在我们在金融行业看到的现有趋势的基础上&#xff0c;而另一些则是完…

学习ftp

文章目录 一、FTP介绍二、两种模式&#xff08;主动模式和被动模式&#xff09;三、FTP配置文件详解四、实际场景举例五、黑白名单六、网络限制 一、FTP介绍 1.FTP&#xff08;File Transfer Protocol&#xff09;是一种应用广泛且古老的互联网文件传输协议。 2.主要应用于互联…

vue项目中定制化音频展示,wavesurfer.js基本使用

效果图&#xff1a; wavesurfer是一个可定制的音频波形可视化&#xff0c;建立在Audio API和HTML5 Canvas之上。 基本使用&#xff1a; <body><script src"https://unpkg.com/wavesurfer.js"></script><div id"waveform"></di…

VMware ESXi和vCenter和vSphere关系是怎样的?

事实上&#xff0c;我们所说的vSphere并不是一个特定的软件。VMware vSphere是VMware的服务器虚拟化软件套件&#xff0c;它包括了许多软件组件&#xff0c;它们中的每一个都在vSphere环境中执行不同的功能。 VMware vSphere的两个核心组件就是VMware ESXi和VMware vCenter Se…

python接口自动化测试(八)-unittest-生成测试报告

用例的管理问题解决了后&#xff0c;接下来要考虑的就是报告我问题了&#xff0c;这里生成测试报告主要用到 HTMLTestRunner.py 这个模块&#xff0c;下面简单介绍一下如何使用&#xff1a; 一、下载HTMLTestRunner下载&#xff1a; 这个模块不能通过pip安装&#xff0c;只能…

ohos的代码同步以及添加自己的代码

首先我们需要获取到官方的repo工具&#xff0c;命令如下curl -s https://gitee.com/oschina/repo/raw/fork_flow/repo-py3 > ./repo&#xff0c;这里我们就拿到repo工具了&#xff0c;这个repo可以放任意地方&#xff0c;也可以放 /usr/local/bin/repo下&#xff0c;这样可以…

C++ 关键字

bool 取值 true和false&#xff0c;只有二者&#xff0c;C编译器会在赋值时将非0值转换为true&#xff0c;0转换为false ture 代表真值&#xff0c;编译器内部用1来表示 false 代表非真值&#xff0c;编译器内部用0来表示 空间 占用一个字节 多个bool变量定义在一起&a…

Power BI 傻瓜入门 13. 进入仪表板

本章内容包括&#xff1a; 配置仪表板将报表功能集成到仪表板中使用基于AI的功能增强仪表板体验基于仪表板规则定义警报 想象一下&#xff1a;图片和文本的混合体整齐地组织起来&#xff0c;就像一块美丽的画布。它告诉你组织中的一切都在顺利运行&#xff0c;但其中一个视觉…