1. 面向对象编程第一单元学习复盘
刚结束面向对象课程第一单元的学习,作为从过程式编程转向面向对象思维的初学者,这个阶段充满了认知重构的挑战。本单元围绕"对象"和"类"这两个核心概念展开,通过三次渐进式作业(多项式求导、表达式解析、表达式优化),让我们在实践中体会封装、继承和多态三大特性。不同于传统教学从理论切入的方式,这种"在实战中领悟"的模式虽然初期痛苦,但确实能建立更深刻的肌肉记忆。
2. 三次作业的架构演进轨迹
2.1 第一次作业:面向过程的惯性思维
首次作业要求实现简单多项式求导,很多同学(包括我自己)实际上是用面向过程的思路完成的。虽然勉强套用了类的形式,但常出现以下典型问题:
- 所有方法都写成static
- 一个类里塞满功能方法
- 用public属性直接操作数据 这种写法本质上还是C语言的函数集合,直到互测阶段看到别人的优秀代码才恍然大悟。
2.2 第二次作业:初识分层设计
加入三角函数和嵌套表达式后,被迫开始思考架构。这时学到的关键经验是:
- 表达式树结构:用组合模式构建AST
- 工厂方法:通过ExpressionFactory统一创建节点
- 递归下降解析:将词法分析和语法分析分离 但此时对接口的使用仍显生硬,经常出现为继承而继承的情况。
2.3 第三次作业:设计模式的实际应用
最复杂的第三次作业要求处理表达式优化,倒逼我们运用设计模式:
- 策略模式:不同化简策略可插拔
- 访问者模式:分离数据结构与操作
- 装饰器模式:逐步添加化简功能 经过三次迭代才明白,好的OOP设计应该像拼乐高——每个类都是独立的积木块,通过标准接口灵活组合。
3. 面向对象思维的五个认知转折点
3.1 从动词思维到名词思维
过程式编程关注"怎么做"(函数),OOP关注"谁来做"(对象)。重构时的明显变化是:
- 方法长度普遍缩短2/3
- 类数量增加3-5倍
- 出现大量xxxManager、xxxHandler类
3.2 封装意识的觉醒
经历几次因随意修改属性导致的bug后,终于理解:
- 所有字段必须private
- getter/setter不是模板代码
- 方法权限要最小化 一个检验标准:修改类内部实现时,不应影响其他类的代码。
3.3 继承的陷阱与救赎
初期滥用继承导致"菱形继承"等问题,后来学会:
- 优先组合而非继承
- 抽象类用于定义模板
- 接口关注行为契约 特别在Java8引入default方法后,接口的灵活性大大提升。
3.4 多态的动态之美
通过一个典型案例体会多态价值:
// 非多态写法 if (obj instanceof TypeA) { ((TypeA)obj).methodA(); } else if (obj instanceof TypeB) { ((TypeB)obj).methodB(); } // 多态写法 obj.commonMethod();当新增类型时,前者需要修改所有判断逻辑,后者只需新增类。
3.5 设计原则的具象化
SOLID原则从抽象概念变成具体工具:
- 单一职责:每个类修改只有一个原因
- 开闭原则:用策略模式实现
- 里氏替换:子类不强化前置条件
- 接口隔离:拆解胖接口
- 依赖倒置:基于抽象交互
4. 单元测试的实战心得
4.1 测试驱动的开发节奏
摸索出的有效工作流:
- 先写测试用例再实现功能
- 每通过一个测试提交一次
- 用Jacoco检查覆盖率 特别在复杂表达式解析时,测试用例能提前暴露设计缺陷。
4.2 Junit的高级用法
超越基础的@Test,更实用的技巧:
- @ParameterizedTest参数化测试
- @DisplayName生成易读报告
- assertAll组合断言
- 用Hamcrest增强可读性
4.3 测试数据的构造艺术
发现几个高效模式:
- 边界值:零、空串、极大值
- 随机生成:用QuickCheck思路
- 变异测试:故意注入错误 一个黄金法则:测试代码应该比实现代码更稳定。
5. 那些教科书没讲的实践细节
5.1 版本控制的正确姿势
在经历几次代码回退后总结:
- 小步提交(原子性变更)
- 有意义的commit message
- 分支策略:master/dev/feature
- .gitignore的合理配置
5.2 代码气味的识别
现在能敏锐察觉这些坏味道:
- 过长的参数列表
- 重复的switch-case
- 基本类型偏执
- 数据泥团 重构时优先使用"提取方法"和"搬移方法"。
5.3 IDE的高效使用
提升效率的关键快捷键:
- Ctrl+Alt+V提取变量
- Ctrl+Alt+M提取方法
- Alt+Enter快速修复
- Ctrl+Shift+T生成测试 特别推荐Structurizr插件可视化依赖关系。
6. 给后来者的学习建议
- 不要过早优化:先保证正确性再考虑性能
- 多读优秀源码:比如JDK的集合框架
- 坚持重构:每天留出20%时间改进
- 善用UML:类图/时序图辅助设计
- 参加Code Review:别人的视角很珍贵
经过这个单元的锤炼,最大的收获不是语法知识,而是思维方式的转变。当开始用对象视角看世界时,突然发现很多系统设计都变得通透——从GUI组件到分布式中间件,面向对象的思想无处不在。这种认知升级的痛苦与快乐,或许就是编程教育的精髓所在。