2011年5月24日星期二

  设计模式之C++实现(二)---策略模式(Strategy)

思想本质:策略模式将具体的策略与用户隔离,用户不知道使用的具体策略,这样我们就可以根据需要灵活地替换我们的策略。

策略模式的类图如下:

}D6S6KX25(B$L7$@M%Q(BEM

Strategy是策略抽象类,有很多的具体策略类继承它,Context负责与用户的交互,同时可以使用不同的具体策略来配置Context。下面我们以对数组的排序

来实现并说明策略模式。

   1: /* abstract strategy class******************************/
   2: class Strategy
   3: {
   4: public:
   5:     virtual void Sort(int array[], int n) = 0;    
   6:     virtual ~Strategy()
   7:     {
   8:     
   9:     }
  10: };
  11:  
  12: /* SelectSortionStrategy class, Strategy's child********/
  13: class SelectSortionStrategy: public Strategy
  14: {
  15:     virtual void Sort(int array[], int n);
  16: };
  17:  
  18: void SelectSortionStrategy::Sort(int array[], int n)
  19: {
  20:     int tag;
  21:     for(int i = 0; i < n-1; i++)
  22:     {
  23:         tag = i;
  24:         for(int j = i+1; j < n; j++)
  25:         {
  26:             if(array[j] < array[tag])
  27:             {
  28:                 tag = j;
  29:             }
  30:         }
  31:  
  32:         int tmp;
  33:         tmp = array[i];
  34:         array[i] = array[tag];
  35:         array[tag] = tmp;
  36:     }
  37: }
  38:  
  39:  
  40:  
  41: /* InsertSortionStrategy class, Strategy's child********/
  42: class InsertSortionStrategy: public Strategy
  43: {
  44:     virtual void Sort(int array[], int n);
  45: };
  46:  
  47: void InsertSortionStrategy::Sort(int array[], int n)
  48: {
  49:     int key;
  50:     for(int i = 1; i < n; i++)
  51:     {
  52:         int j;
  53:         key = array[i];
  54:         for(j = i-1; j >= 0; j--)
  55:         {
  56:             if(array[j] > key)
  57:             {
  58:                 array[j+1] = array[j];
  59:             }
  60:             else
  61:             {
  62:                 break;
  63:             }
  64:         }
  65:         
  66:         array[j+1] = key;
  67:     }
  68: }
  69:  
  70:  
  71: /* Context class****************************************/
  72: class Context
  73: {
  74: private:
  75:     Strategy* m_pStrategy;
  76: public:
  77:     Context(Strategy* pStrategy);
  78:     void ContextSort(int array[], int n);
  79:     ~Context();
  80: };
  81:  
  82: Context::Context(Strategy* pStrategy)
  83: {
  84:     m_pStrategy = pStrategy;
  85: }
  86:  
  87: Context::~Context()
  88: {
  89:     if(m_pStrategy)
  90:         delete m_pStrategy;
  91: }
  92:  
  93:  
  94: void Context::ContextSort(int array[], int n)
  95: {
  96:     m_pStrategy->Sort(array, n);
  97:  
  98: }

排序策略有很多种,这里只实现了插入排序和选择排序,我们通过用不同的策略来配置Context,就可以实现用不同的排序算法来排序。同时可扩展性也好,如

果将来要增加快速排序等策略,只需要派生一个类就可以。单元测试也很方便,各种策略各自封装成一个类,可以进行单独测试。以下是用户端代码示例:

   1: #include <iostream>
   2:  
   3: #include "simpleFactory.h"
   4: #include "strategy.h"
   5:  
   6: using namespace std;
   7:  
   8: void printArray(int array[], int n)
   9: {
  10:     for(int i = 0; i < n; i++)
  11:     {
  12:         cout<<array[i]<<"\t";
  13:     
  14:     }
  15:     cout<<endl;
  16: }
  17:  
  18: int main(int argc, char* argv[])
  19: {    
  20:     // client code
  21:     int a[] = {25,586,58,6958,2564,235,545,658,742,2};
  22:     Context insertContext(new InsertSortionStrategy);    
  23:     insertContext.ContextSort(a, sizeof(a)/sizeof(int));
  24:     printArray(a, sizeof(a)/sizeof(int));
  25:  
  26:     int b[] = {25,586,58,6958,2564,235,545,658,742,2};
  27:     Context selectContext(new InsertSortionStrategy);    
  28:     selectContext.ContextSort(b, sizeof(b)/sizeof(int));
  29:     printArray(b, sizeof(b)/sizeof(int));
  30:  
  31:     return 0;
  32: }

示例中我用两种不同的策略来排序相同的数组,输出结果是一样的。从用户代码可以看到,在创建Context的时候,要是要用具体的策略来配置,也就是说用户

是需要知道Context类和各种具体策略的,这是策略模式的不足,为了弥补这个不足,可以用策略格式和简单工厂模式结合,从而解决由用户来创建策略对象的

问题。

没有评论:

发表评论