题目集8-9总结BLOG

题目集8-9总结

一、前言

题目集8和9是我Java面向对象编程学习道路上一次的重要的“试炼”。这两次题目集共包含6道题目,从基础的点线面问题到复杂的航空货运管理系统,难度循序渐进,很好地培养了我的面向对象编程思维。
题目集8的三个题目像是三个台阶:点线面问题让我实际上手实践、并在其中感受抽象思维;雨刷程序让我认识到了真实世界的复杂性,实际编写程序需要更多的考虑;航空货运管理系统则是一个完整的小型项目体验,让我更加夯实了类的设计能力。
题目集9则在原有基础上进一步深化:魔方问题考验数学与编程的结合能力;点线面容器类问题展示了设计的扩展性;航空货运管理系统的升级版则引入了继承与多态的高级应用。
这些题目见证了我的编程能力从稚嫩到相对成熟的成长过程。每一次调试、每一次重构、每一次"顿悟",都是这段旅程中宝贵的记忆点。

二、核心题目分析:航空货运管理系统

2.1 题目集8的版本:面向对象的基础实践

第一版的航空货运管理系统是一个结合现实情况和需求的项目实践。通过PowerDesigner设计的类图清晰地展现了系统结构:
image

主要类包括:

Customer:客户信息类,包含客户基本属性

Dimensions:货物尺寸类,封装长宽高计算逻辑

Cargo:货物类,核心业务类,负责计算计费重量和运费

Flight:航班类,管理航班信息和载重能力

Order:订单类,整合客户、货物和航班信息

OrderPrinter:订单打印类,负责输出格式化

InputHandler:输入处理类,封装输入逻辑

这个版本中,我主要关注如何把现实世界的概念转化为类和对象。Customer、Cargo、Flight等核心类都是基于现实实体建模的。还有Dimensions类的设计,它将长宽高封装在一起,并提供了体积计算方法,体现了良好的封装性。

复杂度分析

image

使用SourceMonitor生成的报表显示:
• 方法平均复杂度:1.50
• 最大复杂度:4.0
• 类平均方法数:

查看/收起Dimensions类
class Dimensions {
    private final double width, length, height;
    
    public Dimensions(double w, double l, double h) {
        Validator.validatePositive(w, "宽度");
        Validator.validatePositive(l, "长度");
        Validator.validatePositive(h, "高度");
        this.width = w; this.length = l; this.height = h;
    }
    
    public double getVolume() {
        return width * length * height;
    }
}

但回顾起来,这个版本存在明显不足:客户和货物类型处理简单粗暴,大量使用条件判断;支付方式硬编码在订单类中无法应对变化的需求;异常处理也不够完善。这些问题在后续使用中会带来很大的维护困难,需要在下一个题目集中完善。

2.2 题目集9版本:继承与多态的威力

题目集9的航空货运管理系统升级版本让我再次领略了面向对象编程的三大基础特征,尤其是继承和多态。通过阅读和理解详细的题目要求,我绘制了新的类图,它的结构相较于之前的明显更加丰富:

image

复杂度分析

image

使用SourceMonitor生成的报表显示:
• 方法平均复杂度:3.40
• 最大复杂度:7.0
• 类平均方法数:9.75

本次最大的改进正是题目所要求的引入了继承体系和多态机制。通过抽象Customer类和IndividualCustomer、CorporateCustomer子类,我实现了不同客户类型的差异化处理,具体体现如下:

点击查看代码
abstract class Customer {
    protected final double discountRate;
    
    public Customer(..., double discountRate) {
        this.discountRate = discountRate;
    }
    
    public abstract String getCustomerType();
    
    public final double getDiscountRate() {
        return discountRate;
    }
}

class IndividualCustomer extends Customer {
    public IndividualCustomer(...) {
        super(..., 0.9); // 个人用户9折
    }
    
    @Override
    public String getCustomerType() {
        return "个人用户";
    }
}

同样,货物系统也通过Cargo抽象类和NormalCargo、DangerousCargo等子类实现了扩展。这种设计让新增货物类型变得非常简单,只需创建新的子类而不用修改现有代码,这也正是继承的最大优点之一,在这里体现得淋漓尽致。

支付系统的改造也让我印象深刻。通过PaymentMethod接口和多种实现类,系统可以灵活支持各种支付方式,符合开闭原则,改变了之前将“微信支付”、“支付宝支付”嵌在代码中不能修改添加的缺点。

2.3 两个版本的对比感悟

通过这两个版本的对比,我深刻体会到了好的设计带来的巨大优势。第一版虽然功能完整,但扩展困难,也没有体现面向对象编程的三大基础特征;第二版则像是一个有机的系统,可以根据需求增删功能,更加贴合实际需求,轻松应对变化。这让我理解了为什么老师说"面向对象的核心是可维护性,而不仅仅是实现功能"。
航空货运管理系统题目的两次迭代生动展示了软件系统如何从简单实现逐步演进为可扩展的架构。这种演进过程让我深刻体会到良好的设计不是一蹴而就的,而是需要不断重构和改进。在未来的学习和实践中,我将更加注重代码的可扩展性和可维护性,而不仅仅是功能的实现。

三、其他题目的实践与思考

3.1 点线面问题的两次重构

点线面问题的两次迭代是我同样非常珍视的一次学习经历。从最初的简单实现,到引入Element抽象类,再到增加GeometryObject容器类,这个过程完美诠释了"重构"的意义。

第一次做点线面问题时,我按照题目要求实现了基本的Point和Line类,感觉就像建筑工人一块块把砖叠起来一样简单。但当题目集8要求引入Element抽象类时,我最初是困惑的,为什么要多此一举呢?,直到我实现了题目集八中Plane类中多态调用时,我才真正理解了这种设计的扩展性。当我第一次看到同一个Element引用可以正确调用不同子类(Pont、Line、Plane)的display方法时,那种豁然开朗的感觉至今难忘:

点击查看代码
Element[] elements = new Element[]{
    new Point(1, 2),
    new Line(p1, p2, "red"),
    new Plane("blue")
};

for (Element e : elements) {
    e.display(); // 多态调用!
}

这个例子让我明白,好的设计应该不止于简单粗暴地把“砖”一块块叠起来,而是应该像搭积木一样,各个部分可以灵活组合,又有统一接口,以实现程序的扩展性和灵活性,适应不同的功能。

3.2 雨刷程序设计

雨刷程序题目给了我当头一棒。首先,题目中对于各个挡位的速度和变化的要求比较不太容易捋顺,需要静下心来理解。其次是实际程序的实现,最初我试图用一堆if-else解决所有情况,结果代码写着写着就变成了一团乱麻。在经过思考和经过三次重构后,我才找到了相对清晰的结构:

  1. 第一次尝试:简单的条件嵌套 → 难以维护
  2. 第二次尝试:将速度表抽象为二维数组 → 可读性差
  3. 最终方案:分离档位和刻度处理 → 结构清晰
点击查看代码
// 最终方案的核心思路
class SpeedTable {
    private static final int[][] SPEEDS = {
        {0, 0, 0, 0, 0},    // 停止档
        {0, 4, 6, 12, 15},   // 间歇档
        {0, 30, 30, 30, 30}, // 低速档
        {0, 60, 60, 60, 60}  // 高速档
    };
    
    public static int getSpeed(int leverPos, int dialPos) {
        return SPEEDS[leverPos][dialPos];
    }
}

这个过程教会我,面对复杂业务逻辑时,合理的分层和抽象是多么重要。当条件判断变得复杂时,就应该考虑使用表驱动法等更结构化的方法来使得程序的实现更加清晰明了。虽然最终的代码可能还不够完美,但相比最初版本已经有了质的飞跃。

3.3 魔方问题的跨学科体验

魔方问题不仅考验编程能力,还需要扎实的几何知识,它让我意外地重温了高中数学。计算正三棱锥的表面积和体积时,我不得不翻出尘封已久的几何公式来实现题目要求。

当最终正确的结果从我的代码中输出时,我感受到了跨学科学习的乐趣,也正是这个经历让我明白,编程从来不是孤立的技术,而是需要与其他学科知识融会贯通。

四、开发中的挑战与收获

4.1 处理边界条件

在这些题目实现过程中,我经历了无数次调试的痛苦与快乐。最难忘的是在雨刷程序中遇到的一个边界条件bug——当档位已经是最低时继续降档会导致异常。通过System.out.println的"原始"调试方法,我最终锁定了问题:

点击查看代码
public void leverDown() {
    if (this.pos > 1) { // 就是漏掉了这个条件检查!
        this.pos--;
    }
}

这个简单的错误让我花了不少时间进行调试、查找和修改,但同时也让我养成了处理边界条件的好习惯。现在写代码时,我都会特别关注循环的终止条件、参数的边界值等情况。

4.2 代码风格的改进

随着实践的积累,我的代码风格也在不断进化。比较题目集8和题目集9的代码,可以明显看到以下改进:

  1. 命名更加规范:从简单的p1、tmp等名称变为更具描述性的senderAddress、maxLoadCapacity等
  2. 注释更加完善:从几乎没有注释到关键方法都有清晰的文档注释
  3. 结构更加清晰:从把所有逻辑塞进main方法到合理的类职责划分

4.3 团队协作的重要性

虽然这些题目是个人作业,老师也反复强调不能抄袭,这对于我们的学习与实际能力的提升没有帮助。但是在独立完成自己的程序之后,和同学分享自己踩过的坑、分享自己感觉可以完善的地方,学习其他人优秀的地方,自己在以后的实践中再尝试改进,这对于自己的提升非常有益。而且在之后的学习,尤其是工作中,团队的沟通绝对是必不可少的,我们现在正在使用的一个程序几乎没有是一个人独立能够开发出来的,通过这样的学习交流,更加能提升“团队编程”的能力。
这种交流不仅解决了许多具体问题,更重要的是让我认识到编程是一项社会活动,而不是孤独的苦修。别人的思路常常能给我意想不到的启发,这种碰撞产生的火花是独自钻研难以获得的。

五、总结与展望

5.1 本阶段的主要收获

通过题目集8和9的实践,我在以下几个方面有了显著进步:

  1. 面向对象思维:从"用Java写C代码",到真正理解封装、继承、多态的价值
  2. 设计能力:从只关注功能实现到考虑可扩展性、可维护性
  3. 调试技巧:从盲目修改到系统化的问题定位方法
  4. 代码质量意识:从"能运行就行"到追求扩展性以及清晰的代码风格

5.2 仍存在的不足

在取得进步的同时,我也清楚地看到了自己的不足:

  1. 设计模式掌握不够:虽然能应用简单模式,但对复杂模式的理解还很肤浅
  2. 异常处理不完善:常常只考虑正确输入、正常情况,对于异常情况的处理还不够周全
  3. 测试意识薄弱:习惯手动测试而非编写自动化测试用例
  4. 性能考虑不足:算法选择和数据结构使用上还有优化空间

5.3 未来的学习方向

基于这些认识,我计划在下一阶段重点加强以下方面的学习:

  1. 深入理解常用设计模式:特别是工厂模式、策略模式、观察者模式等实用模式
  2. 培养测试驱动开发习惯:从编写测试用例开始设计代码
  3. 学习代码重构技巧:通过课程学习和自主钻研,提升代码质量
  4. 参与实际项目开发:通过更多类似于雨刷模拟和航空货运管理系统的真实项目积累工程经验

题目集8和9就像一把钥匙,为我打开了面向对象编程的大门。虽然前面的路还很长,但我已经找到了正确的方向,也对未来的学习充满期待。这段经历让我明白,编程不仅是一门技术,更是一种思维方式,需要通过不断的实践和思考才能养成、才能有收获。

posted on 2025-05-24 23:00  Yuanyan321  阅读(59)  评论(0)    收藏  举报