菜单项类只存基础字段,价格计算推迟到订单生成时动态执行;订单类每次调用getTotal()都重新累加各菜品最终价格;控制台输入统一用nextLine()+try-catch解析防崩;用ArrayList管理菜单项支持安全增删。

菜单类怎么设计才不重复算价格
菜单项如果直接用 double 存价格,后续做折扣、满减、套餐拆分就容易出错——因为价格逻辑被写死在数据里了。应该把价格计算推迟到订单生成时,靠方法动态算。
- 菜单项类(
MenuItem)只存基础字段:name、basePrice、isVegetarian等,不存“当前售价” - 真正要算钱的地方是
Order类里的calculateTotal()方法,它遍历所有MenuItem实例并调用各自的getFinalPrice() - 如果某道菜有会员价,就在
MenuItem里加个getFinalPrice(CustomerType type),而不是新增一个memberPrice字段
订单类如何避免 add() 后总价不更新
常见错误是把总价存在字段 total 里,然后在 add(MenuItem item) 里忘了重算——结果 getTotal() 返回的还是旧值。
- 不要缓存总价;每次调用
getTotal()都重新遍历items列表并累加item.getFinalPrice() - 如果真要缓存(比如订单很大),必须确保所有修改订单的操作(
add、remove、updateQuantity)都同步更新total字段 - 更安全的做法是去掉
total字段,只留getTotal()方法——Java 中函数调用开销几乎可忽略,省去状态同步的麻烦
控制台输入菜品编号时怎么防崩
用户输个 abc 或空行,Scanner.nextInt() 就抛 InputMismatchException,程序直接退出。这不是功能缺陷,是没处理边界输入。
- 别用
nextInt()直接读编号;先用nextLine()读整行,再用Integer.parseInt()转,包在try-catch里 - 转完检查范围:
if (id menuItems.size()),提示“编号不存在,请重试” - 输入流残留问题:
nextInt()不吞换行符,后面跟nextLine()会立刻返回空字符串——统一用nextLine()+ 解析,最稳
为什么用 ArrayList 而不是数组存菜单项
菜单后期大概率要增删(比如下架菜品、临时加新品),用数组就得手动扩容、复制,错一步就 ArrayIndexOutOfBoundsException。
立即学习“Java免费学习笔记(深入)”;
-
ArrayList<MenuItem>支持动态增删,add()和remove()安全可靠 - 遍历时别用传统 for 循环配
size()——如果循环中删了元素,索引会错位;改用增强 for 或迭代器 - 不需要随机访问性能优化(比如按 ID 查菜),就别提前建
Map<Integer, MenuItem>;先跑通逻辑,再看是否真慢
菜单和订单之间的耦合点其实就两个:一是订单依赖菜单项的定价逻辑,二是编号选择需要菜单长度校验。其他地方越松越好——比如订单类完全不知道菜单怎么打印,也不该知道。










