跳转至

练习:使用策略模式计算折扣


任务描述

设计折扣策略抽象类 DiscountStrategy,让订单类在运行时使用不同折扣算法。

相关知识

策略模式将可替换的算法封装为不同派生类,调用方只依赖共同接口。

策略的替换性

Order 不负责判断“是否打折”;它只保存一个 DiscountStrategy 引用,并将价格计算委托给 apply。更换策略对象即可改变订单行为。

引用生命周期

Order 保存的是策略引用,因此测试中的策略对象必须比订单对象存活更久。本题中的局部变量声明顺序已满足该要求。

编程要求

  1. DiscountStrategy 声明纯虚函数 apply(double price) const
  2. NoDiscount 返回原价;PercentDiscount(0.8) 返回八折价。
  3. Order 保存 const DiscountStrategy&finalPrice() 计算最终价格。
  4. 断言 100 元订单的结果分别为 10080
  5. applyfinalPrice 均为 const 成员函数。
  6. DiscountStrategy 必须具有虚析构函数,Order 不拥有策略对象,因此不得在析构函数中删除策略引用。

待完成代码

#include <cassert>
#include <iostream>
#include <sstream>

// TODO:定义策略类和 Order
void test() {
    NoDiscount normal;
    PercentDiscount sale(0.8);
    assert(Order(100, normal).finalPrice() == 100);
    assert(Order(100, sale).finalPrice() == 80);

    std::ostringstream output;
    std::streambuf* oldBuffer = std::cout.rdbuf(output.rdbuf());
    std::cout << "原价订单:" << Order(100, normal).finalPrice() << '\n';
    std::cout << "折扣订单:" << Order(100, sale).finalPrice() << '\n';
    std::cout.rdbuf(oldBuffer);
    assert(output.str() == "原价订单:100\n折扣订单:80\n");
}

int main() {
    test();
    std::cout << "本关测试通过" << std::endl;
    return 0;
}

测试说明

预期输出为原价 100 和折后价 80。订单类不应包含用于区分折扣种类的 if/switch;新增满减策略时也无需修改 Order


开始你的任务吧,祝你成功!