270
社区成员
发帖
与我相关
我的任务
分享今天上机的 P4 又挂了,不过好在 OOPre 已经结课,正好借这个机会,把这段时间的折腾和收获认真梳理一下。
刚开始做 OOPre 的时候,其实对“几千行的迭代作业”非常恐惧,但真正做下来才发现,难的不是“写多少代码”,而是“怎么把它们组织好”。
一开始做冒险者大陆,只是照着需求往上堆功能:
先是“有冒险者”
然后“有药水”
再加“装备”
后面又补上接口、多态这些
最早我几乎是把各种物品(药水、装备等)都堆在一起,差不多就是“有这个功能就往一个类里塞一点”。直到后来慢慢理解到父类和子类的概念,才开始有意识地给结构“分层”:
把 Bottle 和 Equipment 分出来
再在它们下面扩展具体子类
让 Adventurer 只面对抽象类型,而不是具体实现
这个过程就像真的在搭一个“冒险者大陆”,从一大团乱麻,逐渐变成有层次、有分工的一张图。
第一次比较正式的重构是在第三次作业之后。
当时由于赶时间,第三次作业没能按时交,只能在课后自己写了一个“看起来能跑”的版本。
结果到了第四次迭代时,问题一下子暴露出来:
Bottle 类和 Equipment 类都没有做好父类/子类的划分
新增功能的时候,只能一直往原来的类里塞代码
想扩展就非常痛苦
于是我第一次真正意义上把代码“拆开重写”:
把共性抽到父类里
不同的行为交给子类去实现
虽然花了不少时间,但也第一次体会到:
“一开始设计差一点,后面每一步都在还债。”
第二次印象比较深的重构,是在实现 Bottle 生效逻辑 时。
一开始我想的是:
user 使用 bottle
然后 used 去调用“受击函数”之类的东西
但实践证明这种设计非常别扭,耦合也很混乱。
后来得到一个更顺畅的思路:
给每个冒险者加一个“状态更新函数”
Bottle 只负责触发这个更新
具体“血量怎么变、状态怎么改”由冒险者自己管理
虽然只是逻辑上的一个小变化,但就是从这个点开始,我才真正意识到:
面向对象不是“谁能改谁的属性”,而是“每个对象对自己的状态负责”。
刚接触 JUnit 的时候,我的真实状态是:
“不知道为什么叫 JUnit,也不知道为什么要这么麻烦写测试,只知道评测要 coverage。”
一开始我就是机械地:
按要求写一些测试
想办法把覆盖率打上去
后来在调逻辑的时候,特别是模块之间产生依赖之后,我才慢慢意识到 JUnit 的真正价值。
当所有逻辑揉成一团的时候:
想检查一个小问题
需要跑一大串输入
还经常不知道 bug 究竟出在解析、逻辑,还是状态更新
这个时候如果还只靠 System.out.println,调试的成本会一路爆炸。
在理解了 JUnit 其实就是 Java Unit Test(单元测试) 之后,我的观念变了:
可以只测一个方法
只构造与这个方法相关的少量对象
可以对边界情况、异常情况单独“围剿”
这样做的好处是:
错误范围被控制在很小一块
定位问题更直接
不需要每次都跑一整套命令流
可以说,是在一遍一遍补测试、看覆盖率的过程中,我慢慢学会了:
不要指望一次写完所有正确的代码,
要学会用测试来逼自己发现问题。
从一开始“所有东西写在一起”,到后来给 Bottle、Equipment、Spell(如果有)分层,慢慢体会到:
抽象类 / 接口能避免很多重复代码
父类固定流程、子类填效果,比到处 if-else 舒服太多
当需求变多的时候,一个好的抽象会让人越来越轻松,而一开始乱写会越来越想重构
以工厂模式为例:
刚学的时候我觉得:“这不就是绕个远路,多写一堆类名吗?”
直到作业里加“商店”这一块:
工厂可以保证创建逻辑集中、接口更安全
新增一种物品,只需在工厂里补一小段逻辑
商店那边不用到处改、也不怕外部乱 new 东西
那时候才意识到:
设计模式的本质不是“炫技”,
而是“让未来的改动变简单”。
在做**冒险者关系(上下级)**那次迭代时,我挖了一堆坑:
想搭一棵完整的关系树
过程中发现:
删除冒险者时,没有同步删上下级关系
处理上下级时,忽略了“上级的上级”
一堆边界情况,光用肉眼看代码根本看不全
最后还是借助 JUnit:
写了专门构造多层关系的测试
把各种“奇怪删除顺序”“重复雇佣”等情况都跑了一遍
一点点把逻辑修平
虽然过程比较痛苦,但也让我真正体验到:
面向对象不只是“写类”,
更是围绕对象行为设计一整套、可验证的状态变化系统。
结合这次的学习体验,我自己有两个小建议:
可以在前几次作业前,安排一两个小型架构练习
比如专门练:
如何提取父类消除重复
如何用接口做多态
如何设计工厂、封装创建逻辑
这样在正式大作业前,大家的“第一次踩坑”就可以发生在更小的场景里。
对 JUnit 和测试思路可以再多讲一点
不只是“要达到多少覆盖率”,
而是多讲一些:
什么是“单元”
如何拆分模块
怎么设计有针对性的测试数据
对后面几次大迭代会有非常直接的帮助
总的来说,OOPre 让我从一开始对“几千行代码”的恐惧,变成了现在可以比较平静地拆需求、定结构、写代码、再用测试不断修正的状态。
虽然过程中也有像 P4 这样“上机翻车”的时候,但每次翻车也都在提醒我:
代码不是一下写对的,
而是慢慢设计、慢慢重构、慢慢验证出来的。
也算是为这门课画上了一个有点折腾、但挺有收获的句号。