策略模式(Strategy Pattern)与状态模式(State Pattern)的异同

server/2025/3/15 18:20:05/
相同点
  1. 行为委托
    两者均通过将行为委托给其他对象来实现功能解耦,遵循“组合优于继承”的原则。

    • 策略模式:将算法逻辑委托给具体的策略类。

    • 状态模式:将状态相关的行为委托给具体的状态类。

  2. 类结构相似
    两者在类图结构上高度相似,均包含:

    • 上下文类(Context):持有策略或状态对象的引用。

    • 抽象接口(Strategy/State):定义行为方法的统一接口。

    • 具体实现类(ConcreteStrategy/ConcreteState):实现具体行为。

  3. 开闭原则
    均支持扩展新的策略或状态,无需修改现有代码。


不同点
维度策略模式状态模式
核心目的灵活替换算法管理对象的状态转换
控制权客户端主动选择策略状态对象自动触发状态转换
依赖关系策略之间相互独立状态之间可能相互依赖
生命周期策略的生命周期由客户端管理状态的转换由上下文或状态自身管理
典型场景算法选择(排序、支付方式)对象状态管理(订单、游戏角色状态)
代码复杂度简单,仅需替换策略复杂,需处理状态转换逻辑

应用场景示例

策略模式:支付方式选择
// 抽象策略接口
class PaymentStrategy {
public:virtual void pay(int amount) = 0;
};// 具体策略类:信用卡支付
class CreditCardPayment : public PaymentStrategy {
public:void pay(int amount) override {std::cout << "Paid " << amount << " via Credit Card." << std::endl;}
};// 具体策略类:支付宝支付
class AlipayPayment : public PaymentStrategy {
public:void pay(int amount) override {std::cout << "Paid " << amount << " via Alipay." << std::endl;}
};// 上下文类(订单)
class Order {
private:PaymentStrategy* strategy;
public:void setStrategy(PaymentStrategy* strategy) {this->strategy = strategy;}void checkout(int amount) {strategy->pay(amount);}
};// 使用示例
int main() {Order order;CreditCardPayment creditCard;AlipayPayment alipay;order.setStrategy(&creditCard);order.checkout(100);  // 输出: Paid 100 via Credit Card.order.setStrategy(&alipay);order.checkout(200);  // 输出: Paid 200 via Alipay.
}
状态模式:订单状态管理
// 抽象状态接口
class OrderState {
public:virtual void handle(OrderContext* context) = 0;
};// 具体状态类:待付款
class PendingPaymentState : public OrderState {
public:void handle(OrderContext* context) override {std::cout << "Processing payment..." << std::endl;context->setState(new PaidState()); // 状态转换}
};// 具体状态类:已付款
class PaidState : public OrderState {
public:void handle(OrderContext* context) override {std::cout << "Order is paid. Preparing for shipment." << std::endl;context->setState(new ShippedState());}
};// 上下文类(订单)
class OrderContext {
private:OrderState* state;
public:OrderContext() : state(new PendingPaymentState()) {}void setState(OrderState* newState) {delete state;state = newState;}void proceed() {state->handle(this);}
};// 使用示例
int main() {OrderContext order;order.proceed();  // 输出: Processing payment... → 状态变为 PaidStateorder.proceed();  // 输出: Order is paid. Preparing for shipment. → 状态变为 ShippedState
}

总结

  • 策略模式:关注算法的灵活替换,由客户端主动控制策略的选择。

  • 状态模式:关注对象内部状态的动态转换,状态变化由上下文或状态自身触发。

两者在结构上相似,但设计目标和适用场景不同。策略模式是“静态多态”,而状态模式是“动态多态”


http://www.ppmy.cn/server/175228.html

相关文章

C#—【在不同的场景该用哪种线程?】

C#—【在不同的场景该用哪种线程&#xff1f;】 在C#中有很多种线程操作方法但都运用在不同的场景。 以下是针对不同场景选择 线程&#xff08;Thread&#xff09;、线程池&#xff08;ThreadPool&#xff09;、异步编程&#xff08;async/await&#xff09; 或 后台线程&…

IDEA中链接使用mysql数据库

一、连接mysql 1. 打开idea&#xff0c;在右上角侧边栏有数据库database插件&#xff0c;打开侧边栏点击加号->数据源&#xff0c;可以看到支持很多数据库&#xff0c;选择mysql。 2. 首次使用需要下载驱动程序&#xff0c;不然连接数据库会报错。找到mysql&#xff0c;点击…

STM32U575RIT6单片机(三)

作业1&#xff1a;使用中断控制光电开关打开蜂鸣器 volatile int flag0; //重写中断回调函数 void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin) //void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin) {if(GPIO_PinPhotoElectric_Pin){flag1;} } void HAL_GPIO_EXTI_Fall…

HADOOP环境配置关闭防火墙

关闭防火墙 为了避免出现网络不通的问题&#xff0c;我们可以简单的在集群内部关闭防火墙 输入下面指令 # 关闭防火墙 systemctl stop firewalld #关闭开机自启 systemctl disable firewalld

【零基础入门unity游戏开发——进阶篇】Unity Microphone类处理麦克风相关信息,录制音频并实时处理或保存录制的音频数据

考虑到每个人基础可能不一样,且并不是所有人都有同时做2D、3D开发的需求,所以我把 【零基础入门unity游戏开发】 分为成了C#篇、unity通用篇、unity3D篇、unity2D篇。 【C#篇】:主要讲解C#的基础语法,包括变量、数据类型、运算符、流程控制、面向对象等,适合没有编程基础的…

3.14学习总结

做了几道算法题 水题&#xff0c;使用深搜轻易求解 #include <stdio.h> #include <stdlib.h> int n,num0; int a[15],b[10086][15]; //深搜 int hly(int s,int i) {if(i11){if(sn){//将每种配料所放的质量储存到数组b中for(int i1;i<10;i){b[num][i]a[i];}num;…

DeepSeek 助力 C++ 开发:探索智能编程新境界

这篇文章就会详细讲讲 DeepSeek 在 C 开发里到底能怎么用&#xff0c;从上面说的写代码、找错误、优化性能&#xff0c;到管理项目这些方面&#xff0c;还会给出好多实际的代码例子&#xff0c;讲讲实际用起来是啥情况。目的就是给那些做 C 开发的人&#xff0c;一份全面又详细…

无限使用Typora

下载 Typora https://www.typora.net/#home 安装 找到 /Applications/Typora.app/Contents/Resources/TypeMark/page-dist/static/js/LicenseIndex.180dd4c7.5b0f7af9.chunk.js 文件 打开文件 搜索 e.hasActivated"true"e.hasActivated,修改成 e.hasActivated&…