策略模式
商场收银软件
根据客户所购买商品的单价和数量来收费
需求分析:
1. 输入单价+数量 => 界面逻辑
2. 计算(可能打折或者促销) => 业务逻辑
3. 输出结果 => 界面逻辑
感觉和计算器的逻辑流程差不多,可以用简单工厂模式实现吗?
可以但是不推荐
1. 简单工厂更多的语义是对象的创建问题
2. 而这里所谓的打折或促销的变化,更多的是算法(业务流程)的变化
策略模式较于简单工程模式
- 策略模式和简单工厂模式的UML区别:关联和聚合的区别
而区别在代码上的体现就是:
简单工厂模式侧重创建,接口语义设计更多的是create,返回的也就是对象
策略模式侧重算法切换,接口语义设计更多的是传参使用参数对象的算法,返回的也就是策略 - 针对不同的促销手段类的扩展
如果使用简单工厂类,则需要增加新的类后,还要修改工厂类;而策略模式是不需要的。
策略模式只需要将促销手段类作为属性保存,然后在客户端调用,是可以被context类共享的。
策略模式深度分析:
- Strategy类在策略模式中的定位主要是封装算法或行为。
它的设计重点在于提供一套清晰的接口,使得算法的实现可以被外部的Context对象调用,而不需要关心具体的实现细节。
Strategy类的实例通常不包含任何唯一标识属性,因为它们的主要职责是执行特定的算法逻辑,而非存储数据或状态。 - 在策略模式中,Strategy类就像是一个工具箱中的工具,每个工具(Strategy实例)都有其特定的功能。
Context对象就像是使用者,它可以根据当前的需求从工具箱中选择合适的工具(Strategy实例)来完成特定的任务。
这种设计允许Context对象在运行时灵活地更换所使用的工具,而不需要修改自身的代码。 - Strategy类在策略模式中扮演的是算法提供者的角色,它通过清晰的接口对外提供服务,而内部的具体实现细节对外部使用者是透明的。
这种设计模式鼓励将行为的定义和行为的使用分离,从而促进代码的模块化和可维护性。
C++
#include <algorithm>
#include <iostream>
using namespace std;
#define free_ptr(p) \
if (p) \
delete p; \
p = nullptr;
// Strategt类,定义所有支持的算法的公共接口
class Strategy
{
public:
virtual ~Strategy(){};
virtual void AlgorithmInterface() = 0;
};
// ConcreteStrategy 封装了具体的算法或行为,继承Strategy
class ConcreteStrategyA : public Strategy
{
void AlgorithmInterface()
{
cout << "算法A实现" << endl;
}
};
class ConcreteStrategyB : public Strategy
{
void AlgorithmInterface()
{
cout << "算法B实现" << endl;
}
};
class ConcreteStrategyC : public Strategy
{
void AlgorithmInterface()
{
cout << "算法C实现" << endl;
}
};
// Context,用一个ConcreteStrategy来配置,维护一个对Strategy的引用
class Context
{
public:
Context(Strategy *strategy) : m_strategy(strategy){};
~Context() { free_ptr(m_strategy); }
void AlgorithmInterface()
{
m_strategy->AlgorithmInterface();
};
private:
Strategy *m_strategy;
};
int main()
{
Context *ContextA = new Context(new ConcreteStrategyA());
Context *ContextB = new Context(new ConcreteStrategyB());
Context *ContextC = new Context(new ConcreteStrategyC());
ContextA->AlgorithmInterface();
ContextB->AlgorithmInterface();
ContextC->AlgorithmInterface();
free_ptr(ContextA);
free_ptr(ContextB);
free_ptr(ContextC);
return 0;
}
C
#include <stdio.h>
// 定义策略函数指针类型
typedef void (*StrategyFunc)(void);
// 定义策略结构体
typedef struct
{
StrategyFunc strategyActioin;
} Strategy;
// 实现具体的策略A
void StrategyA()
{
printf("算法A实现\n");
}
// 实现具体的策略B
void StrategyB()
{
printf("算法B实现\n");
}
// 实现具体的策略C
void StrategyC()
{
printf("算法C实现\n");
}
// 定义上下文结构体,用于封装策略
typedef struct
{
Strategy strategy;
} Context;
// 创建上下文并设置策略
Context createContext(StrategyFunc strategy)
{
Context context;
context.strategy.strategyActioin = strategy;
return context;
}
int main()
{
// 创建不同的上下文,每个上下文使用不同的策略
Context contextA = createContext(StrategyA);
Context contextB = createContext(StrategyB);
Context contextC = createContext(StrategyC);
// 执行不同的策略
contextA.strategy.strategyActioin();
contextB.strategy.strategyActioin();
contextC.strategy.strategyActioin();
return 0;
}