练习:使用策略模式计算折扣¶
任务描述¶
设计折扣策略抽象类 DiscountStrategy,让订单类在运行时使用不同折扣算法。
相关知识¶
策略模式将可替换的算法封装为不同派生类,调用方只依赖共同接口。
策略的替换性¶
Order 不负责判断“是否打折”;它只保存一个 DiscountStrategy 引用,并将价格计算委托给 apply。更换策略对象即可改变订单行为。
引用生命周期¶
Order 保存的是策略引用,因此测试中的策略对象必须比订单对象存活更久。本题中的局部变量声明顺序已满足该要求。
编程要求¶
DiscountStrategy声明纯虚函数apply(double price) const。NoDiscount返回原价;PercentDiscount(0.8)返回八折价。Order保存const DiscountStrategy&,finalPrice()计算最终价格。- 断言
100元订单的结果分别为100、80。 apply和finalPrice均为const成员函数。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。
开始你的任务吧,祝你成功!