又来到了这个环节------OOP作业总结

时隔近一个月的时间,经历了:

的磨砺,我本人对于面向对象的知识也更加充实,所幸我都得到了满分

 

 不过,话说回来最近的大作业难度逐步趋升,我有恐慌说最后一次迭代要么从我代码里割大动脉,要么写不出来

代码人代码魂

 

但不可否置的是,随着迭代加深,不少问题也浮出水面。



一、家具程序的类设计及类更迭

---------------------------------------------------------------------------第一次迭代类图(纯串联电路)

第一次家具电路是纯串联模式,包含的电路模式复杂度其实不算很高,所以我在这里偷了点懒

说是偷懒,但是我也在第一次的设计里考虑到了下一次添加并联的情况:

首先是类的设计:

  • 设置Equipment父类,用于存储所有设备共性,如引脚编号、引脚电压、设备名称
  • 由父类设置功能性方法入口,由继承子类重写方法并具体实现
  • 各子类设置独属于自己的参数,如转速、流明亮度、档位等等,并根据各自功能实现不同重写父类方法

其次是电路连接设计:

  • 将输入而来的所有设备单个添加进链表,链表存储顺序即为输入的顺序
  • (偷懒的地方)  给每个引脚设定编号,在根据输入内容连接电路时,根据输入的引脚号给每个引脚依次编号1、2、3、4、5……
  • 串接电路则根据编号依次赋电压值,不同设备两引脚电压相等,同设备经计算后再赋值

其他方面设计:

  • 对于输入的处理我用了“边输边存”的形式
  • 对于电路输入信息和设备调控信息分开处理
  • (偷懒的地方)  当改动开关状态时,将索引至VCC处电压赋0或220,以来使整条电路关闭或打开

 

(那么以上是我对第一次迭代的设想,抛开别的先不谈,当从这里向下展望第二次迭代时,我天真的以为:多加几个链表存储并联电路,然后并联电路的引脚编号由1-1进化至2-1……

但是,这在我刚刚着手做第二次迭代时就被我自己否定了。)

因为本身纯串联电路对于考虑后续的并联电路收益不大,所以在第二次迭代则费了很大劲,o(╥﹏╥)o

---------------------------------------------------------------------------第二次迭代类图(串并联电路)(放大更清晰  ヾ(✿°▽゚)ノ

 很明显的是,两张类图产生极大的变化,就连设备父类Equipment的类图大小都变了,因为这次迭代我换了一个新的思路

(但是同时设计思路的改变也埋下隐患)

 

这次我重新设计了解决方案,把电路元器件与电路剥离,从Equipment作为电路节点的1.0版本更新至由Circuit作为电路节点的2.0版本

我把元器件的电路特征都抽离出来,然后将这个节点代表的设备作为Circuit类里的一个属性,这样的话,只要我接好电路,把电位差向元器件传入则可获得最后值

让我来理顺整个思路:

首先是类的设计:

  • 新增Circuit类:抽离元器件的电路特征属性至Circuit里,将元器件设为Circuit的一条属性
  • 变Equipment类为abstract抽象类:加入抽象方法:更改引脚电压方法,设定元器件参数方法,计算设备属性方法,show方法等
  • 各子类继承自抽象父类并实现上述四个抽象方法

其次是电路连接:

  • 在完成设备新增与参数配置环节后,首先进行统一的开关检查,对于每一条路的综合开关状态转递至整条路的启用与否
  • 根据得来的电路状态计算总电阻与并联电路分流比例
  • 以计算串联干路电流、并联各支路电流,再乘以改元器件电阻的方式来计算属于该元器件的电压降(电位差)
  • 传递由 V = I * R 得来的电压降,传入用电设备计算转速和流明亮度

其他方面:

  • 使用公式 以代替  来计算并联电路电阻计算,同时前一公式可以推广到迭代三和四
  • 在对元器件名称排序时,因为存储的是String类型,则按字典序排序则K1和K100都将优先于K2,因此,修改排序方法以正确排序

  •  给并联电路的IN和OUT单独建类,同时设置一个静态值作为进出并联电路的电压,则可以做到非同一个链表之间的相同值传递

  • 削弱元器件开关的作用,转嫁至Circuit类的元器件活跃状态属性中

 

那么基于以上的设计,程序实现就变得思路清晰了一点。

但是也仅仅是针对正常电路能够实现,各种元器件的组合仍有不少问题有待处理

二、测试问题的解决

              ❉电路里含有超多个开关

针对这个问题,我最初的设想是:当改动开关状态时,将索引至VCC处电压赋0或220,以来使整条电路关闭或打开

但是当有一个开关输入,赋一次VCC,再有一个,再赋一次VCC,这样一个一个的输入再改变赋值,直接就造成了电路判断错误

所以后来将开关状态判断单独摘出来,作为一个独立环节:

---------------------------------------------------------------------------判断电路开关状态-伪代码

 1  boolean allJudge=true;
 2         for(int j=0;j<list.size();j++){
 3             if(list.get(j).getName().startsWith("K")){
 4                 if(!list.get(j).deviceActivation){
 5                     allJudge=false;
 6                     break;
 7                 }
 8             }
 9         }
10         if(allJudge){
11             setONorOFF(list,1);
12         }else{
13             setONorOFF(list,0);
14         }

例如此,通过判断所有的开关状态来确定整条路的启用状态与否

 

              ❉电压计算的精确度

这个问题本来不算是个问题,因为在题目中提到了非输出结果时,一律以double类型值来计算,所以本应该不存在精度计算

但是,总会有但是,当落地扇这个具有梯度电压转速的元器件诞生后,使得精度计算被写入测试点(通过测试,可能有这一点)

也就是说:

假如落地扇转速 260r/s 的对应电压在 [120 , 140) 区间内,即使139.9999999999992,也将视为260r/s

可是这个值是在电压比电阻,在电阻乘电流时产生的小数计算误差

意即这个值应视为140v,对应到360r/s

所以,在这里要进行数据修正:对于类似上述例子的,偏差值在十万分之一的,应当向最近的整数值向上舍入

---------------------------------------------------------------------------精度计算-伪代码

1 public static double roundSpecific(double number) {//精度计算
2         int nearestInteger = (int) Math.round(number);
3         if (Math.abs(number - nearestInteger) < 0.000001) {
4             return nearestInteger;
5         } else {
6             return number;
7         }
8     }

有如上述代码,则可修正数据

 

三、代码质量分析

---------------------------------------------------------------------------迭代一 SourceMonitor数据分析图

 这样看起来,我的迭代一的代码也算得上是非常垃圾了

没有单一职责原则遵循的不多,开放封闭几乎没有,因为迭代二换思路了

每个Tool工具的静态方法大多以for、if else等堆砌,其实有点又回到了C语言的编程习惯了

平均复杂度和平均平均嵌套深度很直白的反映了这一点,在深度柱状图中表明,各方法都编写的不是很好

所以迭代一很失败,不可否置

但是迭代二换了思路,同时也为下一次迭代做了准备

也可以说是脱胎换骨

---------------------------------------------------------------------------迭代二 SourceMonitor数据分析图

 迭代二的数据分析,先不说别的,深度柱状图看起来就很优秀,也印证了我的思路和方法是有一定的正确性的

平均方法与深度都有了明显的改观,在迭代二中我也更注重了单一职责原则

为了能够使代码的复用性提升,我也在代码内介入了不少接口,在下一次迭代都能用到,但是对电路的判断仍然需要更改

 

四、两次迭代的总结与收获

第一次迭代:

  • 第一次迭代的存在的最大问题就是设计考虑的不全面,以致于后续写代码像打补丁一样
  • 电路连接的设计过于依赖串联,无法进行改造
  • 代码复用性不高,单个方法的圈复杂度处于极高水平

第二次迭代:

  • 相较于上一次,对于整体设计与思路有了较为明显的改观,思路也很明确
  • 但是电路连接没有能加入错误链接检查的地方,依赖于输入全部为正确的
  • 单一职责普及到了每个方法,提高了代码复用性
  • 设计思路以电流电阻合成电压计算电压降,意在方便计算,但同时为电压输出与电路连接埋下隐患

两次迭代:

  • 作业的类设计层没有封顶就开始写代码,以致于后期要缝缝补补才能勉强满分
  • 对于类的封装不够严谨,类本身的行为有部分被抽离到了工具方法
  • 各种名称有对应的完整名称,带有一部分的注释,再加上方法单一职责,所以对于哪一部分是做什么的还是很清楚地
  • 好多处理方法依附于if-else和for,使得代码的嵌套层级有些深,使用linkedlist时的向下循环也有套3~4层for的

总的来说,收获还是比较大的,对于多态和接口的应用开始走向成熟化,设计思路更加趋向于严谨

尤其是抽象类的继承,算是在我这里玩得明白了

个人能力有待加强,也要不断的去学习更多的新的东西。

 

 


 


 

 (正经事说完了,再说点不正经的)(bushi)

这题目真的,我哭死

首先呢,如果真的按照实际情况考虑说,问题肯定是层出不穷的,所以自主去发掘自己代码的问题所在肯定是没问题的

为了发掘测试点,我对所有的控制器件,用电器件和开关都做了一遍组合,结果上PTA才三十几分

所以我又去找PTA的测试点,发现了包括精度,短接等在内的好多测试点

所以这个测试点的提示不公开真是一手好套路 

 

posted on 2024-06-03 11:40  AuroraBorealis-wx  阅读(58)  评论(0)    收藏  举报