前言
一些话
我认为,在编程语言这一大类中,类图、时序图等图形化表达方式能够清晰地展示程序的设计思路和结构,而代码本身则是这一思路的具体实现。相比之下,文字虽然能够提供一定的描述,但往往只能表达一些表面层次的内容,无法深入展现程序的精妙之处。只有通过阅读代码,才能真正体会到其中的巧妙与细节。因此,在我前两篇博客中,我特意粘贴了一些精妙的代码块。为了避免文章中代码过多显得冗长,我将每个代码块都进行了折叠处理,以减少视觉上的负担,然而,这样的做法却让我遭遇了较低的评分。为了迎合评分标准,迫于现实压力,在这次作业中,我对文章中的代码进行了大幅删减。尽管我认为这影响了读者对程序的理解,但为了妥协于评分要求,我只能作出这样的调整。
关于题目
这次题目的知识覆盖面相当广泛,涵盖了继承、多态等核心概念,并深入要求合理应用多种设计模式。题目的逐步升级不仅反映了学习要求的提升,也强调了编程实践中“高内聚、低耦合”原则的重要性,这对于确保代码的可维护性和易于迭代至关重要。尽管本次仅设置了两道题目,但其难度相较于以往有了显著的提升,尤其是在最后一次题目迭代中,整个班级没有人取得满分。这一挑战主要体现在对复杂方法的设计以及电路模拟的精确把控上,充分展现了题目的深度和广度。
设计与分析
作业7 7-1 家居强电电路模拟程序-3
设计
思路
围绕电路模拟的核心功能展开,通过定义多个类(如 CircuitEquipment
、SeriesCircuit
和 ParallelCircuit
)来表示不同类型的电路设备和电路结构,利用面向对象的设计原则实现设备的多态性和灵活性。输入解析部分使用正则表达式处理用户输入,确保能够灵活应对多种格式,同时在电路逻辑实现中,通过方法如 connect()
和电气计算方法(如 calResistance()
和 calCurrent()
)来维护电路的连接关系和计算电气参数,从而构建一个可扩展且易于维护的电路模拟器。
类图
计算部分时序图
分析
报表数据
从图中可以得知
- 代码中有较多的注释,说明代码有较高的可读性和维护性。
- 类中的方法数较少,意味着每个类的功能较为单一,符合单一职责原则。
- 平均复杂度和平均深度较低,说明代码整体上较为简单,易于理解和维护。
- 最大深度和最大复杂度较高,表明存在一些较为复杂的代码块,需要进一步优化。
主要类与功能
- Main: 程序的入口,负责读取用户输入并调用相应的方法来构建电路。
- CircuitEquipment: 抽象类,定义了电路设备的基本属性和方法,包括电压、电流和电阻的计算。
- VCC: 代表电源设备,设置电压为220V。
- Switch: 抽象类,表示控制设备,能够控制电路的开关状态。
- SeriesCircuit 和 ParallelCircuit: 分别表示串联和并联电路,负责计算电路的总电阻和电流。
- ControlledEquipment: 受控设备的抽象类,定义了电压范围和电流计算的方法。
- Fan、Lamp、Governor: 具体的受控设备实现,分别表示风扇、灯具和调速器。
设计模式
- 工厂模式:
CircuitEquipment.create()
方法根据输入字符串创建不同类型的电路设备。 - 策略模式:
ControlEquipment
类及其子类(如Switch
)可以根据不同的控制逻辑来改变电路的行为。 - 组合模式:
SeriesCircuit
和ParallelCircuit
类可以包含多个CircuitEquipment
对象,形成复杂的电路结构。
CircuitEquipment 类
功能:
作为所有电路设备的基类,定义了电路设备的基本属性(如电压、电流、电阻等)和方法(如计算电流、调整设备、连接设备等),提供了一个静态工厂方法 create()
,根据输入字符串创建不同类型的电路设备。
设计特点:
- 抽象类: 通过将其定义为抽象类,强制子类实现特定的方法,确保每种电路设备都有一致的接口。
- 封装性: 将设备的属性(如电压、电流等)封装在类内部,提供公共方法进行访问和修改。
SeriesCircuit 类
功能:
表示串联电路,负责连接多个电路设备并计算总电阻和电流,提供了 create()
方法,以及 connect()
方法用于连接设备,calResistance()
和 calCurrent()
方法分别计算电路的总电阻和电流。
设计特点:
- 连接逻辑: 通过
connect()
方法实现设备之间的连接,确保电路的逻辑关系清晰。 - 电流和电压计算: 提供了
calResistance()
和calCurrent()
方法,分别计算电路的总电阻和电流,体现了电路的物理特性。
ParallelCircuit 类
功能:
表示并联电路,能够连接多个电路设备并计算总电阻和总电流, 提供了 create()
和 connect()
方法用于添加设备。
设计特点:
- 灵活性: 允许动态添加设备,适应不同的电路结构。
- 电压分配: 在
calAnyVoltage()
方法中,所有设备共享相同的电压,符合并联电路的特性。
VCC 类
功能:
代表电源设备,设置电压为220V,并提供连接其他设备的功能。
设计特点:
- 简单明了: 该类的设计非常简单,主要负责设置电压和连接设备,符合单一职责原则。
- 重写
connect()
方法: 通过重写connect()
方法,确保电源设备的连接逻辑符合电路的需求。
设计心得
- 可扩展性: 该设计允许用户轻松添加新的电路设备,只需继承
CircuitEquipment
类并实现必要的方法。 - 灵活性: 通过使用正则表达式解析输入,系统能够处理多种格式的输入,增强了用户体验。
- 复杂性管理: 通过将不同类型的电路和设备分开管理,代码的复杂性得到了有效控制,便于后期维护和扩展。
作业8 7-1 家居强电电路模拟程序-4
设计
思路
本次作业的难度相比于上次显著增加,电路的复杂性也随之提升。由于原有代码在考虑情况时不够全面,直接在其基础上进行修改以适应这次作业变得非常困难。因此,我对原有代码进行了大规模的重构,最终才完成了现在的代码。在这次作业中,我为每个设备设定了相应的引脚(这一点在之前的迭代中被忽略),设备之间的连接则是通过引脚进行设置的,以及对于相连设备间的操作都是通过引脚来进行的。引脚在这段代码中起到了关键作用,负责设备之间的连接和电流传输。通过灵活的引脚设计,电路模拟器能够有效地管理设备的状态和行为。
类图
设备连接时序图
分析
数据报表
从图中可以得知
- 注释百分比较高,说明代码有较高的可读性和维护性。
- 类中的方法数较少,意味着每个类的功能较为单一,符合单一职责原则。
- 平均复杂度和平均深度较低,说明代码整体上较为简单,易于理解和维护。
- 最大深度和最大复杂度较高,表明存在一些较为复杂的代码块,需要进一步优化。
引脚
引脚是我在这次代码迭代中新增加的一个功能,在这里我将着对于引脚进行着重讲解。
引脚的定义
在 CircuitEquipment
类中,我定义了一个 Pair<CircuitEquipment, Integer>[] pin
数组,用于表示设备的引脚。每个引脚由一个 Pair
对象表示,其中 first
是连接到该引脚的设备,second
是该设备的引脚编号。
引脚的功能
- 连接设备: 引脚用于连接不同的电路设备。通过
connect(int outPin, CircuitEquipment device, int inPin)
方法,设备可以将其输出引脚连接到另一个设备的输入引脚。这种连接方式使得电路的构建变得灵活和动态。 - 电流传输: 在电路中,电流通过引脚在设备之间传输。每个设备可以通过其引脚接收电流并将其传递给连接的设备。引脚的设计使得电流的流动可以被有效地管理和计算。
- 电压设置: 引脚还用于设置和获取电压。每个引脚可以存储与之相关的电压值,设备可以通过引脚来调整其工作状态。例如,在
setPinVoltage(int i, double pinVoltage)
方法中,可以为特定引脚设置电压。
引脚在不同电路中的应用:
- 串联电路(SeriesCircuit): 在串联电路中,引脚用于连接设备并传递电流。每个设备的输出引脚连接到下一个设备的输入引脚,形成一个线性电流路径。
- 并联电路(ParallelCircuit): 在并联电路中,引脚用于将多个设备并行连接。每个设备的引脚可以独立接收电压,从而实现并行电流分配。
电路的计算
在 calResistance()
和 calCurrent(double begVoltage)
方法中,引脚的作用尤为明显。电路设备通过引脚获取连接设备的电压和电流,从而进行电阻和电流的计算。这种设计使得电路的计算过程能够递归进行,确保每个设备都能根据其连接状态正确计算电流和电压。
CircuitEquipment类
职责
是所有电路设备的基类,定义了电路设备的基本属性和方法。它包含引脚数组 pin[]
,用于管理设备的连接。
主要方法
connect(int outPin, CircuitEquipment device, int inPin)
: 连接当前设备的输出引脚到另一个设备的输入引脚。setPinVoltage(int i, double pinVoltage)
: 设置特定引脚的电压。calResistance()
: 计算设备的电阻。calCurrent(double begVoltage)
: 根据输入电压计算电流。- 引脚功能: 通过引脚,设备可以与其他设备连接,形成电路网络,支持电流和电压的传输。
Diode类
1 //二极管 2 class Diode extends ControlledEquipment { 3 4 int type; 5 public Diode(String name, int type) { 6 setName(name); 7 setID(Integer.parseInt(name.substring(1))); 8 this.type = type; 9 10 if (type == 0) { 11 setResistance(0); 12 } else { 13 setResistance(1 / 0.0); 14 } 15 setLimitCurrent(8); 16 } 17 18 @Override 19 public void setVoltage(double voltage) { 20 super.setVoltage(voltage); 21 } 22 23 @Override 24 public void show() { 25 System.out.print("@P" + getID() + ":"); 26 if (type == 0) { 27 System.out.print("conduction "); 28 } else { 29 System.out.print("cutoff "); 30 } 31 double[] v = getPinVoltage(); 32 System.out.print((int)v[1] + "-" + (int)v[2]); 33 34 if (getCurrent() > getLimitCurrent()) { 35 System.out.println(" exceeding current limit error"); 36 } else { 37 System.out.println(); 38 } 39 } 40 }点击展开Diode类
职责
具体的电路设备类,表示二极管。它负责控制电流的流动方向,是本次迭代中新增加的类。
主要方法
calCurrent(double begVoltage)
: 根据输入电压计算电流,并考虑二极管的特性。show()
: 显示二极管的状态。
用途
二极管通过引脚连接到其他设备,确保电流只能在一个方向流动。
踩坑心得
迭代坑点
在代码设计的过程中,严格遵循“高内聚,低耦合”的原则是至关重要的。这一理念强调模块或组件应当紧密围绕其单一职责进行组织,同时减少它们之间的相互依赖,以便于维护、扩展和重用。遗憾的是,在本次作业迭代的实践中,我未能充分贯彻这一理念。
在作业需求的初步分析阶段,尽管已经明确指出设备需要包含“引脚”这一关键属性,但由于我短视地认为前几轮作业无需此属性即可完成,因此忽略了它在设计中的重要性,并做出了不引入“引脚”的决定。这一疏忽在后续的迭代中引发了连锁反应,尤其是在第四次作业迭代时,我不得不对代码进行大规模的修改,以重新整合“引脚”功能。
这一过程不仅耗时费力,而且极易引入错误,严重影响了开发效率和代码质量。这次经历深刻地提醒我,在设计之初就应充分预见未来的功能扩展需求,并据此构建灵活、可扩展的代码架构。只有这样,才能在面对需求变更时迅速而准确地做出调整,确保代码的持续稳定性和可维护性。
希望同学们将以此为鉴,在未来的项目实践中更加注重前期的需求分析和架构设计,力求在源头上避免类似的困境,确保代码的高质量和可维护性。
未解决的坑点
最后一次作业的坑点很多(可能也不应该叫做坑点,只是我感觉很难实现),比如一个设备中电路的方向会因为电路情况而发生改变,如图:
这种情况需要有良好的电路设计才能够正常输出答案(比如我的代码不能够正确输出)。
改进建议
- 引脚的设置:这次代码中将引脚的数量设置为了10个,在之后的改进中应该考虑将引脚数量从固定的 10 个改为动态管理,允许用户根据需要添加或删除引脚。这可以通过使用动态数组或集合(如 ArrayList)来实现。
- 电压电流的计算:对于电流和电压的计算,可以考虑使用策略模式,将不同的计算策略封装为独立的类,便于扩展和维护。
总结
不足
在最近的两次作业迭代过程中,我深刻体会到了优秀代码设计的重要性。由于我在前期未能充分重视这一方面,导致最终不得不对代码进行大规模重构以满足新的需求和标准。尽管这次重构最终帮助我完成了作业,但其中所经历的挑战与曲折让我感到自责与懊悔。
学到了
这次经历教会了我许多宝贵的经验教训。首先,预见性是高质量代码设计的关键要素之一。一个良好的设计不仅仅是实现当前的功能要求,还需要考虑未来可能的变化和发展。这就需要我们在编写每一行代码时都要有长远的眼光,思考其在未来维护和扩展中的可能性。其次,灵活性同样不可或缺。灵活的设计能够使代码更容易适应变化的需求,减少后期调整的成本和风险。最后,我认为更加注重前期的需求分析和架构设计至关重要。这不仅有助于确保代码的可维护性和可扩展性,还可以提高开发效率,降低错误发生的概率。
本学期的收获以及想说的话
这次作业作为本门课程的压轴大作业,不仅标志着本学期课程学习的圆满落幕,也见证了我个人在面向对象程序设计领域从零到一的巨大飞跃。在这一系列精心设计的作业训练中,我经历了从迷茫困惑到逐渐掌握,再到熟练运用的过程,我的编程能力和逻辑思维都得到了前所未有的提升。
然而,在收获成长的同时,我也深刻反思了自己在作业迭代过程中暴露出的诸多不足。特别是在面对需要不断迭代完善的任务时,我发现自己往往难以在初次设计时就构思出一个既符合当前需求又便于未来扩展的优秀方案。这导致我在实现最后一次作业时,不得不对之前的代码进行大规模的重构,以适应新的功能和要求。
回顾整个学期的学习历程,我深刻体会到面向对象程序设计不仅是一门技术,更是一种思维方式。它教会了我如何以更加抽象和模块化的方式来思考和解决问题,如何在复杂多变的环境中保持代码的清晰和简洁。这些宝贵的经验和教训将成为我未来学习和工作中的重要财富,指引我不断前行,追求卓越。
标签:总结,题目,引脚,代码,电路,程序设计,电流,连接,设备 From: https://www.cnblogs.com/tunecoming/p/18565914