miniyuan
面向对象技术引论第二次作业
题 1
题 2
题 3
问题:
- 函数命名不具体:
doAnything没有说明具体作用; - 命名风格不一致:既有驼峰式
inputString又有下划线式type_id; - 魔法数字:使用了很多魔法数字,如
101、1、2、3等; - 一行多条语句:如第 2 行和第 8 行;
- 缩进混乱:如第 5 行未缩进;
- 缺少大括号:代码中的
if else均未使用大括号包裹; - 运算符两侧空格不一致:第 6 行
type_id==2前后缺少空格; - 注释无意义:第 3 行
// 打印结果注释无意义; - 缺少防御性编程:没有检查空指针、缓冲区溢出等。
建议修改为:
// 消除魔法数字
const int MAX_INPUT_LEN = 100;
// 消除魔法数字
enum class ResultType {
RUNTIME_ERROR = 1,
OUTPUT_STRING = 2,
TIME_EXCEEDED = 3
}
// 函数命名具体化
// 统一使用下划线式
// 使用 const 增强安全性
int print_result(const char *input_string, ResultType type_id) {
// 防御性编程
if (input_string == nullptr) {
std::cerr << "Error: null input string" << std::endl;
return -1;
}
// 防御性编程
if (std::strlen(input_string) > MAX_INPUT_LEN) {
std::cerr << "Error: input too long" << std::endl;
return -1;
}
char buffer[MAX_INPUT_LEN + 1];
std::strcpy(buffer, input_string);
// 使用大括号包裹
// 统一缩进
if (type == ResultType::RUNTIME_ERROR) {
std::cout << "Runtime Error" << std::endl;
} else if (type == ResultType::OUTPUT_STRING) {
std::cout << buffer << std::endl;
} else if (type == ResultType::TIME_EXCEEDED) {
std::cout << "Time Exceeded" << std::endl;
} else {
// 防御性编程
std::cerr << "Error: invalid type" << std::endl;
return -1;
}
return 0;
}
题 4
-
策略模式
解决的设计问题:优惠规则(满减、折扣券、会员价等)属于频繁变化且可相互替换的算法,可以使用策略模式。
如何应用:定义抽象接口
DiscountStrategy,并由独立实现满减、折扣券、会员价等具体价格计算算法。 -
观察者模式
解决的设计问题:订单状态发生变化时,需要及时通知顾客、后厨和配送人员。
如何应用:将订单作为被观察者,维护一个观察者列表。当订单状态变更时,订单对象自动调用
notifyObservers()广播通知。 -
命令模式
解决的设计问题:修改订单、取消订单等操作需要支持撤销(Undo)和重做(Redo)。
如何应用:将修改菜品、取消订单等操作封装为独立的命令对象,均实现包含
exec()和undo()的抽象命令接口。 由命令调用器维护一个命令栈,执行时压栈,撤销时弹出并调用undo()恢复原状态。 -
桥接模式
解决的设计问题:系统需要支持不同终端设备(自助点餐机、手机端、收银台)和不同支付平台(微信、支付宝、银行卡),不适合采用多层继承。
如何应用:将终端设备作为抽象层,如
TerminalAbstraction,将支付平台作为实现层,两者通过聚合关系连接。新增终端或支付渠道时,只需在对应维度扩展。 -
外观模式
解决的设计问题:点餐系统背后涉及菜单浏览、库存校验、支付结算、订单通知等多个复杂子系统。
如何应用:在高层定义
OrderFacade统一接口,封装选餐、下单、支付、通知的完整流程。 各终端只需调用OrderFacade.placeOrder()等简单方法,由外观类内部协调各子系统。