目录

组件协作_Strategy


组件协作模式

现代软件专业分工之后的第一个结果是"框架与应用程序"的划分 组件协作是通过晚期绑定, 来实现框架和应用之间的松耦合, 是二者协作时常用的模式 典型模式有: Template Method, Strategy, Observer/Event

1 Strategy 策略模式

1.1 模式动机

在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂; 而且有时候支持不使用的算法也是一个性能负担。 如何在运行时根据需要透明地更改对象的算法?将算法与对象本身解耦,从而避免上述问题?

1.2 模式定义

定义一系列算法,把它们一个个封装起来,并且使它们可互相巷换(变化)。该模式使得算法可独立手使用它的客户程序(稳定)而变化(扩展,子类化)。

1.3 模式示例代码

# include <iostream>
# include <string>

// 抽象策略类,定义计算税收的接口
class TaxStrategy {
public:
    virtual double calculateTax(double income) const = 0;
    virtual ~TaxStrategy() {}
};

// 具体策略类,实现不同国家的税收计算规则
class ChinaTaxStrategy : public TaxStrategy {
public:
    double calculateTax(double income) const override {
        // 中国的税收计算规则
        return income * 0.25;
    }
};

class USATaxStrategy : public TaxStrategy {
public:
    double calculateTax(double income) const override {
        // 美国的税收计算规则
        return income * 0.30;
    }
};

class UKTaxStrategy : public TaxStrategy {
public:
    double calculateTax(double income) const override {
        // 英国的税收计算规则
        return income * 0.20;
    }
};

class JapanTaxStrategy : public TaxStrategy {
public:
    double calculateTax(double income) const override {
        // 日本的税收计算规则
        return income * 0.15;
    }
};

// 环境类,根据具体策略计算税收
class TaxCalculator {
private:
    TaxStrategy* strategy;

public:
    TaxCalculator(TaxStrategy* strategy) : strategy(strategy) {}

    void setStrategy(TaxStrategy* newStrategy) {
        strategy = newStrategy;
    }

    double calculateTax(double income) const {
        return strategy->calculateTax(income);
    }
};

int main() {
    double income = 100000.0;

    TaxStrategy* chinaStrategy = new ChinaTaxStrategy();
    TaxCalculator calculator(chinaStrategy);
    double chinaTax = calculator.calculateTax(income);
    std::cout << "中国的税收:" << chinaTax << std::endl;

    TaxStrategy* usaStrategy = new USATaxStrategy();
    calculator.setStrategy(usaStrategy);
    double usaTax = calculator.calculateTax(income);
    std::cout << "美国的税收:" << usaTax << std::endl;

    TaxStrategy* ukStrategy = new UKTaxStrategy();
    calculator.setStrategy(ukStrategy);
    double ukTax = calculator.calculateTax(income);
    std::cout << "英国的税收:" << ukTax << std::endl;

    TaxStrategy* japanStrategy = new JapanTaxStrategy();
    calculator.setStrategy(japanStrategy);
    double japanTax = calculator.calculateTax(income);
    std::cout << "日本的税收:" << japanTax << std::endl;

    delete chinaStrategy;
    delete usaStrategy;
    delete ukStrategy;
    delete japanStrategy;

    return 0;
}

2 要点总结

  • Strategy 及其子类为组件提供了一系列可重用的算法,从而可以使得类型在运行时方便地根据需要在各个算法之间进行切换。
  • Strategy 模式提供了用条件判断语句以外的另一种选择,消除条件判断语句,就是在解耦合。含有许多条件判断语句的代码通常都需要 Strategy 模式。
  • 如果 Strategy 对象没有实例变量,那么各个上下文可以共享同一个 Strategy 对象,从而节省对象开销。