C++策略模式详解:从基础到高级应用
1. 策略模式基础回顾在C中策略模式是一种行为设计模式它允许在运行时选择算法或行为。这种模式的核心思想是将算法封装在独立的类中使得它们可以相互替换。策略模式让算法的变化独立于使用它的客户端。1.1 基本结构解析典型的策略模式包含三个关键组成部分策略接口(Strategy Interface)定义所有支持的算法或行为的公共接口具体策略(Concrete Strategies)实现策略接口的具体算法类上下文(Context)维护对策略对象的引用并将工作委托给策略对象// 策略接口 class SortingStrategy { public: virtual ~SortingStrategy() default; virtual void sort(std::vectorint data) 0; }; // 具体策略A升序排序 class AscendingSort : public SortingStrategy { public: void sort(std::vectorint data) override { std::sort(data.begin(), data.end()); } }; // 具体策略B降序排序 class DescendingSort : public SortingStrategy { public: void sort(std::vectorint data) override { std::sort(data.begin(), data.end(), std::greaterint()); } }; // 上下文 class Sorter { std::unique_ptrSortingStrategy strategy; public: void setStrategy(std::unique_ptrSortingStrategy newStrategy) { strategy std::move(newStrategy); } void executeSort(std::vectorint data) { if(strategy) { strategy-sort(data); } } };1.2 策略模式的优势策略模式的主要优势在于开闭原则可以在不修改现有代码的情况下引入新策略消除条件语句避免了大量的if-else或switch-case语句运行时灵活性算法可以在运行时动态切换单一职责每个策略类只负责一个算法或行为提示当发现类中有多个条件分支处理相似但不同的行为时考虑使用策略模式重构。2. 策略模式进阶实现2.1 使用模板策略在C中我们可以利用模板来实现编译时策略选择这提供了更好的性能但牺牲了运行时的灵活性。templatetypename Strategy class Context { Strategy strategy; public: void execute(const std::vectorint data) { strategy.process(data); } }; struct FastProcessing { void process(const std::vectorint data) { // 快速处理实现 } }; struct PreciseProcessing { void process(const std::vectorint data) { // 精确处理实现 } }; // 使用示例 ContextFastProcessing fastContext; ContextPreciseProcessing preciseContext;2.2 策略工厂模式结合工厂模式可以更灵活地创建和管理策略对象class StrategyFactory { public: static std::unique_ptrSortingStrategy createStrategy(const std::string type) { if(type ascending) { return std::make_uniqueAscendingSort(); } else if(type descending) { return std::make_uniqueDescendingSort(); } return nullptr; } };2.3 策略与多线程在多线程环境中使用策略模式需要注意线程安全问题class ThreadSafeContext { std::mutex mtx; std::unique_ptrSortingStrategy strategy; public: void setStrategy(std::unique_ptrSortingStrategy newStrategy) { std::lock_guardstd::mutex lock(mtx); strategy std::move(newStrategy); } void executeSort(std::vectorint data) { std::lock_guardstd::mutex lock(mtx); if(strategy) { strategy-sort(data); } } };3. 实际应用案例分析3.1 游戏AI行为策略在游戏开发中策略模式常用于实现不同的AI行为class AIBehavior { public: virtual ~AIBehavior() default; virtual void execute(GameCharacter character) 0; }; class AggressiveBehavior : public AIBehavior { public: void execute(GameCharacter character) override { // 攻击最近的玩家 } }; class DefensiveBehavior : public AIBehavior { public: void execute(GameCharacter character) override { // 寻找掩体并治疗 } }; class NeutralBehavior : public AIBehavior { public: void execute(GameCharacter character) override { // 随机移动 } }; class GameCharacter { std::unique_ptrAIBehavior behavior; public: void setBehavior(std::unique_ptrAIBehavior newBehavior) { behavior std::move(newBehavior); } void update() { if(behavior) { behavior-execute(*this); } } };3.2 数据解析策略在处理不同格式的数据时策略模式也非常有用class DataParser { public: virtual ~DataParser() default; virtual Data parse(const std::string input) 0; }; class JSONParser : public DataParser { public: Data parse(const std::string input) override { // JSON解析实现 } }; class XMLParser : public DataParser { public: Data parse(const std::string input) override { // XML解析实现 } }; class CSVParser : public DataParser { public: Data parse(const std::string input) override { // CSV解析实现 } }; class DataProcessor { std::unique_ptrDataParser parser; public: void setParser(std::unique_ptrDataParser newParser) { parser std::move(newParser); } Data process(const std::string input) { if(parser) { return parser-parse(input); } throw std::runtime_error(No parser set); } };4. 性能优化与最佳实践4.1 策略对象复用频繁创建和销毁策略对象可能影响性能可以考虑对象池模式class StrategyPool { std::unordered_mapstd::string, std::shared_ptrSortingStrategy pool; public: std::shared_ptrSortingStrategy getStrategy(const std::string type) { auto it pool.find(type); if(it ! pool.end()) { return it-second; } std::shared_ptrSortingStrategy strategy; if(type ascending) { strategy std::make_sharedAscendingSort(); } else if(type descending) { strategy std::make_sharedDescendingSort(); } if(strategy) { pool[type] strategy; } return strategy; } };4.2 策略与缓存结合对于计算密集型策略可以结合缓存机制class CachedStrategy : public SortingStrategy { std::unique_ptrSortingStrategy wrapped; mutable std::unordered_mapsize_t, std::vectorint cache; public: explicit CachedStrategy(std::unique_ptrSortingStrategy strategy) : wrapped(std::move(strategy)) {} void sort(std::vectorint data) override { size_t key std::hashstd::string{}(std::string(data.begin(), data.end())); auto it cache.find(key); if(it ! cache.end()) { data it-second; return; } wrapped-sort(data); cache[key] data; } };4.3 策略模式与STL结合现代C中我们可以使用函数对象和lambda表达式作为轻量级策略class GenericSorter { std::functionvoid(std::vectorint) strategy; public: templatetypename F void setStrategy(F f) { strategy std::forwardF(f); } void execute(std::vectorint data) { if(strategy) { strategy(data); } } }; // 使用示例 GenericSorter sorter; sorter.setStrategy([](std::vectorint v) { std::sort(v.begin(), v.end()); });5. 常见问题与解决方案5.1 策略选择逻辑复杂化当策略选择逻辑变得复杂时可以考虑使用策略工厂将选择逻辑封装在工厂类中引入规则引擎对于非常复杂的选择逻辑策略组合模式允许策略的组合使用class CompositeStrategy : public SortingStrategy { std::vectorstd::unique_ptrSortingStrategy strategies; public: void addStrategy(std::unique_ptrSortingStrategy strategy) { strategies.push_back(std::move(strategy)); } void sort(std::vectorint data) override { for(auto strategy : strategies) { strategy-sort(data); } } };5.2 策略间状态共享当策略需要共享状态时上下文传递通过上下文对象共享状态策略管理器集中管理策略和共享状态观察者模式策略间通过事件通信class SharedContext { std::unordered_mapstd::string, std::any state; public: templatetypename T void set(const std::string key, const T value) { state[key] value; } templatetypename T T get(const std::string key) const { return std::any_castT(state.at(key)); } }; class ContextAwareStrategy : public SortingStrategy { std::shared_ptrSharedContext context; public: explicit ContextAwareStrategy(std::shared_ptrSharedContext ctx) : context(std::move(ctx)) {} void sort(std::vectorint data) override { // 可以使用context中的共享状态 } };5.3 策略模式与类型擦除当需要处理不同类型的策略时可以使用类型擦除技术class AnyStrategy { struct Concept { virtual ~Concept() default; virtual void sort(std::vectorint) 0; }; templatetypename T struct Model : Concept { T impl; explicit Model(T t) : impl(std::move(t)) {} void sort(std::vectorint data) override { impl.sort(data); } }; std::unique_ptrConcept impl; public: templatetypename T AnyStrategy(T t) : impl(new ModelT(std::forwardT(t))) {} void sort(std::vectorint data) { if(impl) impl-sort(data); } };6. 现代C中的策略模式演进6.1 使用std::variant实现策略模式C17引入的std::variant可以用来实现类型安全的策略模式using StrategyVariant std::variantAscendingSort, DescendingSort, RandomSort; class VariantContext { StrategyVariant strategy; public: templatetypename T void setStrategy(T s) { strategy std::forwardT(s); } void execute(std::vectorint data) { std::visit([data](auto s) { s.sort(data); }, strategy); } };6.2 策略模式与概念(Concepts)C20的概念(Concepts)可以更好地约束策略接口templatetypename T concept SortingStrategy requires(T t, std::vectorint v) { { t.sort(v) } - std::same_asvoid; }; templateSortingStrategy T class ConceptContext { T strategy; public: ConceptContext(T s) : strategy(std::move(s)) {} void execute(std::vectorint data) { strategy.sort(data); } };6.3 策略模式的性能考量在选择策略模式实现方式时需要考虑以下性能因素虚函数开销传统实现有虚函数调用开销内存占用策略对象的内存使用情况缓存友好性数据局部性对性能的影响编译时优化模板策略可以更好地优化提示在性能关键路径上考虑使用模板策略或内联策略(lambda)来减少运行时开销。