课程总结
面向对象程序设计课程总结性Blog
(1)前言:课程内容与学习概况
本门面向对象程序设计课程通过多样化的教学环节构建了完整的知识体系,涵盖理论学习、实践编程与设计思维培养。从工作量来看,PTA作业占据核心地位,包含多个题目集,如电梯调度系统、航空货运管理系统、图形卡片排序等,题目数量多且逻辑复杂度逐步提升。以电梯调度为例,从单类设计迭代到多类协作,再到引入乘客类和请求队列优化,代码量从数百行扩展到上千行,需要深入理解状态管理、请求队列调度等复杂逻辑。
Blog作业则要求对PTA代码进行深度分析,结合SourceMonitor代码度量工具和PowerDesigner类图,探讨设计原则的应用与代码质量优化,每次Blog需完成类图分析、复杂度评估及设计模式改进建议,工作量较大但对理解面向对象设计有显著帮助。
实验环节紧密配合PTA作业,通过动手编码实现理论知识,线上课程提供了面向对象基础概念讲解,线下课程则侧重设计原则的案例分析与代码评审,整体形成了“理论-实践-反思”的学习闭环。难度方面,初期PTA题目(如圆柱体体积计算、线性方程求解)侧重基础语法,中期(电梯调度、航空货运)转向复杂业务逻辑与设计模式应用,后期(图形继承、集合框架)则考验综合运用能力,呈现由浅入深的梯度。
题目之间的逻辑关联与能力进阶路径
一、PTA作业的难度梯度与知识演进
1. 基础编程阶段(题目集1-3)
以"编写程序.docx"中的基础题为例,从圆柱体体积计算、摄氏温度转换等简单计算问题,到求各位数之和、日期换算等逻辑处理,逐步引入变量定义、输入输出、条件判断等基础语法。如7-1题求解线性方程时,首次接触Cramer法则的算法实现,而7-2题对三个整数排序则为后续复杂排序算法奠定基础,知识点从"单一计算"过渡到"逻辑流程控制"。
2. 类设计入门阶段(题目集4-6)
电梯调度系列作业呈现明显的迭代式设计特征:
- PTA5单类设计:将电梯状态、请求队列、运行逻辑封装在Elevator类中,重点掌握属性封装与方法定义,如currentFloor、direction等属性的getter/setter设计。
- PTA6多类拆分:遵循单一职责原则,拆分为Elevator(状态管理)、RequestQueue(请求队列)、Controller(调度控制),引入ExternalRequest类处理外部请求,体现"类职责分离"思想。
- PTA7乘客类添加:新增Passenger类管理源楼层与目标楼层,外部请求处理逻辑从"方向判断"升级为"路径规划",需将外部请求的目标楼层加入内部队列,复杂度提升体现在请求队列的动态转换。
3. 设计模式应用阶段(题目集7-9)
航空货运管理系统的两次迭代典型体现设计原则的深化:
- 首次作业:Goods类实现Chargeable接口,通过calculateRate()方法的条件判断处理普通货物费率,符合接口隔离原则。
- 二次作业:新增危险货物、加急货物类型,原条件判断升级为策略模式——定义RateStrategy接口,为不同货物类型实现独立策略类,解决了calculateRate()方法复杂度从15飙升至22的问题,体现从"简单多态"到"设计模式优化"的跨越。
二、知识点的纵向关联与横向迁移
1. 核心技术的螺旋式提升
- 封装:从初期将计算逻辑封装为方法(如圆柱体体积计算),到中期将业务逻辑封装为类(电梯调度),再到后期通过接口封装行为(Chargeable接口),封装的粒度从"代码块"升级到"模块"。
- 继承:图形卡片排序作业中,Point/Line/Plane继承Element抽象类,而航空货运中Customer/Sender/Recipient继承Person类,前者侧重"图形形态"的继承,后者侧重"用户属性"的继承,展示继承在不同业务场景的应用。
- 集合框架:从数组存储(如判断两数组是否相同)到LinkedList管理请求队列(电梯调度),再到ArrayList存储订单明细(航空货运),体现从"固定容量"到"动态数据结构"的认知升级。
2. 跨题目知识迁移案例
- 电梯调度的队列管理为航空货运的订单处理提供思路:两者均需处理"请求-响应"流程,电梯的内外请求队列设计直接启发了货运系统中订单队列与货物明细的管理方式。
- 图形类的多态展示与电梯状态机设计存在逻辑共性:图形对象通过display()方法实现多态输出,电梯通过不同状态(MOVING/STOPPED)的行为差异实现状态机模式,本质都是"同一接口,不同实现"的多态思想应用。
3. 错误处理的渐进式完善
- 初期题目(如圆形类半径校验)仅处理"非法数值",输出"Wrong Format"。
- 中期电梯作业增加"重复请求过滤"(如忽略连续相同楼层请求)和"无效楼层忽略"(超出最大楼层的请求)。
- 后期航空货运引入"订单重量超限检测",当货物重量超过航班载重量时终止程序,错误处理从"输入校验"扩展到"业务规则校验"。
三、Blog作业与PTA作业的闭环反馈机制
1. 设计分析对编码实践的指导
- 通过SourceMonitor分析Goods.java的复杂度(如二次作业中calculateRate()复杂度22),促使在PTA代码中引入策略模式重构,将方法复杂度降至10以下。
- 类图分析发现电梯类职责过重(如PTA5的Elevator类包含500行代码),推动在PTA6中拆分为Elevator/Controller/RequestQueue三类,符合单一职责原则。
2. 编程实践对设计理论的验证
- PTA中电梯调度的"同方向请求优先处理"逻辑,在Blog作业中通过状态转换图和时序图进行理论建模,验证了"先来先服务"与"最短路径优先"的算法差异。
- 航空货运的费率计算从"硬编码条件判断"到"策略模式动态切换"的重构过程,在Blog中通过UML类图和代码度量数据,直观展示设计模式对代码质量的提升(如方法调用次数减少37%)。
(2)知识关联总结:从碎片化到体系化的认知构建
整个课程作业体系呈现"基础语法→类设计→设计模式→架构优化"的清晰脉络:
- 横向维度:每个知识点(如封装)在不同题目中以不同难度级别重复出现,从"属性私有化"到"模块封装",再到"接口隔离",形成螺旋上升的认知曲线。
- 纵向维度:单个题目集(如电梯调度)通过3次迭代(单类→多类→乘客类),逐步引入继承、集合、状态机等技术,体现"简单需求→复杂场景"的开发实战流程。
这种题目设计不仅确保初学者能从基础入手,更通过前后关联的问题场景,帮助建立"面向对象设计是解决复杂问题的系统性方法"的核心认知,为后续大型项目开发奠定方法论基础。
(2)面向对象技术总结:核心知识与掌握情况
一、封装:数据隐藏与职责分离
- 掌握情况:在PTA作业中,通过private修饰符实现属性封装,如Elevator类的currentFloor、direction等属性均通过getter/setter访问。航空货运管理系统中,Goods类将计费重量、费率计算封装为私有方法,外部仅通过public接口调用,符合单一职责原则。
- 认知提升:理解封装不仅是语法层面的属性私有化,更重要的是将相关功能聚合到单一类中,如Order类专注订单管理,避免功能混杂。
- 欠缺之处:初期作业中存在过度暴露属性的问题(如直接访问List集合),后期通过Collections.unmodifiableList()优化,但对封装粒度的把握仍需加强。
二、继承与多态:代码复用与动态行为
- 实践案例:电梯调度程序中,通过抽象类Element派生出Point、Line、Plane类,利用多态实现不同图形的display()方法;航空货运系统中,Person抽象类派生出Customer、Sender、Recipient,统一管理地址、电话等公共属性。
- 技术应用:多态在排序场景中尤为关键,如图形卡片排序作业中,通过Comparable接口实现不同图形按面积排序,体现“同一操作作用于不同对象产生不同行为”的特性。
- 不足:对里氏替换原则的理解不够深入,曾在子类重写父类方法时修改了返回值类型,导致程序异常,后续通过单元测试发现并修正。
三、抽象类与接口:行为抽象与契约定义
- 应用场景:航空货运系统中,Chargeable接口统一货物计费逻辑,Goods类实现接口以支持不同类型货物(普通、危险、加急)的费率计算;电梯调度中,Direction枚举定义上下行方向,State枚举管理电梯状态(运行、停止、空闲)。
- 设计优势:通过接口隔离原则,避免类实现不必要的方法,如Plane类仅需实现display()方法,无需关心图形坐标计算。
- 待改进:接口设计时有时过度追求“大而全”,如早期电梯接口包含过多无关方法,后期通过重构拆分为独立接口(如RequestHandler、DirectionController)。
四、集合框架:数据结构与算法应用
- 常用容器:电梯调度中使用LinkedList管理请求队列,航空货运中用ArrayList存储货物明细,图形作业中通过ArrayList
实现容器类的增删遍历。 - 泛型实践:在RequestQueue类中使用泛型(如LinkedList
),避免类型转换异常,提升代码安全性。 - 性能问题:初期在处理大量请求时直接使用ArrayList,未考虑随机访问与插入效率,后期根据场景切换为LinkedList,优化了请求队列的动态操作性能。
五、异常处理与JavaFX:健壮性与可视化
- 异常处理:在身份证校验位计算、日期类设计中,通过try-catch捕获非法输入(如负数半径、无效日期),并输出“Wrong Format”提示。但早期作业存在异常处理不完整的问题,如未处理NullPointerException,导致程序崩溃。
- JavaFX应用:课程后期实验中尝试使用JavaFX实现电梯调度可视化,通过Stage、Scene和Button组件模拟电梯运行状态,但对事件监听、界面布局的掌握仍停留在基础层面,复杂动画效果实现困难。
(3)采坑心得:从错误中学习的实践经验
一、类设计缺陷导致的耦合问题
- 典型案例:首次电梯作业中,将所有逻辑封装在Elevator类中,导致类行数超过500行,calculateRate方法复杂度高达22(超过建议阈值15)。修改货物类型时需大量修改原代码,违背开闭原则。
- 解决方案:通过策略模式重构,定义RateStrategy接口,为普通货物、危险货物实现独立策略类,将费率计算逻辑从Goods类解耦,复杂度降至10以下。
二、输入校验缺失引发的程序异常
- 问题场景:航空货运系统中未校验货物重量(如输入-5kg),导致体积重量计算出错;日期类设计中未验证月份范围(如2月30日),引发逻辑错误。
- 改进措施:在属性setter方法中添加校验逻辑,如:
public void setWeight(double weight) {
if (weight < 0) {
throw new IllegalArgumentException("重量不能为负数");
}
this.weight = weight;
}
并在Main类中使用try-catch捕获异常,提示用户重新输入。
三、字符串硬编码与扩展性不足
- 代码反例:支付方式解析使用if-else判断字符串(如if (payMethod.equals("ALiPay"))),新增支付方式需修改多处代码,违背开闭原则。
- 优化方案:引入工厂模式,通过PaymentFactory根据代码创建支付实例:
public static Payment createPayment(String code) {
switch (code) {
case "ALiPay": return new AlipayPayment();
case "WeChat": return new WeChatPayment();
default: throw new IllegalArgumentException("无效支付方式");
}
}
四、复杂条件判断与代码可读性
- 问题表现:电梯调度的determineDirection方法中嵌套5层if-else,逻辑难以理解,维护成本高。
- 重构手段:将方向判断逻辑拆分为独立方法,如isUpRequest()、hasSameDirectionRequest(),并使用策略模式替换部分条件判断,提升代码可读性。
(4)改进建议与课程总结:面向未来的学习方向
一、对课程设计的改进建议
- 教学内容优化:
- 增加设计模式的实战案例,如在讲解策略模式时,直接以航空货运的费率计算为例,演示从if-else到策略模式的重构过程。
- 补充JavaFX进阶内容,如动画效果、数据绑定,避免仅停留在按钮和文本框的基础使用。
- 作业布置调整:
- 在PTA作业中增加单元测试要求,如为DateUtil类编写测试用例,验证nextNDays和previousNDays的正确性。
- 分阶段提供类图框架,如先给出抽象类Element的定义,再让学生实现子类,减少设计盲区。
二、个人技术提升方向
- 设计模式深化:系统学习工厂模式、观察者模式在电梯调度中的应用,如当电梯状态变化时自动通知请求队列更新。
- 代码质量把控:使用SonarQube等工具进行代码静态分析,控制方法复杂度(≤15)、类行数(≤300),避免重复代码。
- 异常处理完善:学习异常链设计,区分业务异常(如InvalidInputException)和系统异常(如NullPointerException),提升程序健壮性。
三、课程总结与学习感悟
本门课程通过“理论讲解-代码实践-设计分析”的闭环教学,使我系统掌握了面向对象的核心技术。从初期编写简单的圆柱体体积计算,到后期实现支持多策略的航空货运系统,每一次作业都是对设计思维的锤炼。印象最深刻的是电梯调度的迭代设计,从单类实现到多类协作,再到遵循单一职责原则拆分控制器、队列、乘客类,深刻体会到“好的设计不是一蹴而就,而是逐步演进”的道理。
面向对象不仅是一种编程技术,更是一种问题分解的思维方式。未来学习中,我将继续强化设计模式的应用,注重代码的可维护性与扩展性,同时加强测试驱动开发(TDD)实践,确保程序在复杂场景下的稳定性。感谢课程中每一次踩坑与重构,让我对“软件设计是一门平衡的艺术”有了更真切的认知。