zoukankan      html  css  js  c++  java
  • 策略模式笔记

    UML类图入下 :

    解决的问题 :

    • 减少代码中的 if  else 语句
    • 简化了单元测试
      • 不同算法独自成类,可以分别进行测试

    注意点:

    • 可以用简单工厂结合策略模式

    算法对象接口为Alorithm.hpp

    #ifndef _ALGORITHM_H_ 
    #define _ALGORITHM_H_ 
    
    class Algorithm {
    public:
        Algorithm() { };
        ~Algorithm() { };
    
        virtual double getMinDist(int x1, int y1, int x2, int y2) { return 1.0; }
    };
    #endif	// _ALGORITHM_H_
    

    两个继承了Algorithm的子类DijkstraSpfa

    • 可以分别编写测试类DijkstraTestSpfaTest,简化了测试
    #ifndef _DIJKSTRA_H 
    #define _DIJKSTRA_H 
    #include "Algorithm.hpp"
    
    class Dijkstra : public Algorithm {
    public:
        Dijkstra() { }
        ~Dijkstra() { }
    
        virtual double getMinDist(int x1, int y1, int x2, int y2) { return 1.0; }
    };
    #endif	// _DIJKSTRA_H
    
    
    #ifndef _SPFA_H 
    #define _SPFA_H 
    #include "Algorithm.hpp"
    
    class Spfa : public Algorithm {
    public:
        Spfa() { };
        ~Spfa() { };
    
        virtual double getMinDist(int x1, int y1, int x2, int y2) { return 1.0; }
    };
    
    #endif	// _SPFA_H
    

    一个AlgoContext类可以拥有Algorithm对象父类指针

    并对外暴露一个调用接口计算的方法

    #ifndef _ALGOCONTEXT_H 
    #define _ALGOCONTEXT_H 
    
    #include "Algorithm.hpp"
    
    class AlgoContext {
    public:
    
        // Context可以拥有一个或多个接口指针
        Algorithm* algo;
    
        AlgoContext(Algorithm* _algo) { this->algo = _algo; }
        ~AlgoContext() { }
    
        double getResult(int x1, int y1, int x2, int y2) {
            // context会根据不同的algo子类调用不同的算法求最短路
    
            return this->algo->getMinDist(x1, y1, x2, y2);
        }
    };
    
    
    #endif	// _ALGOCONTEXT_H
    

    最后是调用方main函数里调用,但是这里有一个类的创建问题

    • 可以使用简单工厂实现解耦
    • 书上推荐使用工厂+策略模式结合的方法(不需要工厂类)
    // 未结合工厂  调用方需要一大堆if else
    #include "AlgoContext.hpp"
    #include "Dijkstra.hpp"
    #include "Spfa.hpp"
    
    signed main() {
    
        AlgoContext context(NULL);
    
        // 这里的对象创建问题可以用 “简单工厂” 模式解决
        // 书上引入了 "策略模式+简单工厂"的结合模式(不需要工厂类)
        if (edgeCount > 2e5) {
            // 稠密图用Dijkstra+堆优化
            context.algo = new Dijkstra();
        }
    
        if (edgeCount < 2e5) {
            // 稀疏图用Spfa
            context.algo = new Spfa();
        }
    
        double result = context.getResult(0, 0, 100, 100);
        cout << "最短路长度 : " << result << endl;
    
        return 0;
    }
    

    策略模式结合简单工厂模式的代码如下

    AlgoContext

    • // 策略模式结合简单工厂
      class AlgoContext {
      public:
      
          // Context可以拥有一个或多个接口指针
          Algorithm* algo;
      
          enum TYPE_ALGORITHM { TYPE_DIJKSTRA, TYPE_SPFA };
      
          AlgoContext(int edgeCount) { 
              this->algo = AlgoContext::getInstance(edgeCount);
          }
          ~AlgoContext() { }
          
          static Algorithm* getInstance(int edgeCount) {
              // 根据入参不同 new 出不同的对象 (简单工厂)
              if (edgeCount > 2e5) { return new Dijkstra(); }
              if (edgeCount <= 2e5) { return new Spfa(); }
              return 0;
          }
      
          double getResult(int x1, int y1, int x2, int y2) {
              // context会根据不同的algo子类调用不同的算法求最短路
              return this->algo->getMinDist(x1, y1, x2, y2);
          }
      };
      

    结合简单工厂后的main调用方只需要2行代码(调用方简化了一堆if else)

    • 如果调用方是界面类,那么 算法和界面 就解耦了

    • signed main() {
          int x1 = 0, y1 = 0, x2 = 100, y2 = 100;
      
          // 书上引入了 "策略模式+简单工厂"的结合模式(不需要工厂类)
          // 如果调用方是界面类,那么 算法和界面 就解耦了
          AlgoContext context(edgeCount);
          double dist = context.getResult(x1, y1, x2, y2);
      }
      
  • 相关阅读:
    SQL考点例题解析
    数据交换技术
    网络安全的攻击手段
    实词和虚词
    VBA代码
    宏代码
    常用模块
    常用模块
    模块和包
    模块介绍
  • 原文地址:https://www.cnblogs.com/majiao61/p/14881356.html
Copyright © 2011-2022 走看看