Post

策略者模式

策略者模式

起因

针对不同的类别,算法多样。如果按照if-else分支写,没加一个类别,就要多一个分支。修改的成本会逐渐上升。

根据设计模式,把分类拖到运行时,找到算法中的共同点,抽象成接口

代码

比如税法的计算, 不同的地区有不同的税法。比如说传输,不同的传输有不同的传输策略。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
enum class TransportType {
  kTcp,
  kUdp,
  kAut,
  kAutPlain,
};

class Sender{
public:
  SendBuffer(const char* data) {
    if (type_ == TransportType::kTcp) {
        // send strategy ...
    } else if ...
    ....
  } 
  TransportType type_;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Class BaseTransportStratagy{
public:
  virtual ~BaseTransportStratagy() {}
  virtual void SendBuffer(const char* data) = 0;
};

class TcpTransport : public BaseTransportStratagy {
public:
  void SendBuffer(const char* data) override; 
};

class UdpTransport : public BaseTransportStratagy {
public:
  void SendBuffer(const char* data) override; 
};


class ConcretCarrier{
public:
  SendBuffer(const char*); // 可以用factory method创建出具体的transport去承担传输的任务,将变化拖到运行时
  BaseTransportStratagy* transport_;
};
......

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
enum TaxBase {
	CN_Tax,
	US_Tax,
	DE_Tax,
	FR_Tax       //更改
};

class SalesOrder{
    TaxBase tax;
public:
    double CalculateTax(){
        //...
        
        if (tax == CN_Tax){
            //CN***********
        }
        else if (tax == US_Tax){
            //US***********
        }
        else if (tax == DE_Tax){
            //DE***********
        }
		else if (tax == FR_Tax){  //更改
			//...
		}

        //....
     }
    
};

税法的计算都比较统一,不如把他往上提.配合工厂模式的使用,做到一套代码计算,扩展只需要额外补充plugin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
class TaxStrategy{
public:
    virtual double Calculate(const Context& context)=0;
    virtual ~TaxStrategy(){}
};


class CNTax : public TaxStrategy{
public:
    virtual double Calculate(const Context& context){
        //***********
    }
};

class USTax : public TaxStrategy{
public:
    virtual double Calculate(const Context& context){
        //***********
    }
};

class DETax : public TaxStrategy{
public:
    virtual double Calculate(const Context& context){
        //***********
    }
};



//扩展
//*********************************
class FRTax : public TaxStrategy{
public:
	virtual double Calculate(const Context& context){
		//.........
	}
};


class SalesOrder{
private:
    TaxStrategy* strategy;

public:
    SalesOrder(StrategyFactory* strategyFactory){
        this->strategy = strategyFactory->NewStrategy();
    }
    ~SalesOrder(){
        delete this->strategy;
    }

    public double CalculateTax(){
        //...
        Context context();
        
        double val = 
            strategy->Calculate(context); //多态调用
        //...
    }
    
};
This post is licensed under CC BY 4.0 by the author.

Trending Tags