301
社区成员
发帖
与我相关
我的任务
分享
(白色类为 HW1 即存在的类,蓝色类为 HW2 时添加,绿色类为 HW3 时添加)
replacer 的 functions 中Replacer将所有的函数展开,并经由Simpilifier化简Parser对表达式进行解析,找出其中的运算符,将表达式逐渐分解为多个Term的加减,Term又分解为多个因子/Term相乘。直至解析出最基本的因子:常数、幂函数、指数函数。Term、Polynomial进行运算,得到最终的表达式+、-进行了处理。(此时的预处理操作在Parser中进行。)Left op Right的形式,再对Left和Right继续进行解析,直至表达式中不再含有运算符。此时表达式为最基本的两种因子之一:常数/幂函数。Polynomial,其余的Add、Sub、Mul都是继承自Polynomial。所有因子都视为简单的Polynomial,不设置单独的类。Replacer、Function用于自定义函数的展开。读取表达式前,将自定义函数存储在 Replacer 的 functions 中。解析表达式前,Replacer将所有的自定义函数展开。Term,由最基本的三种因子组成:常数、幂函数、指数函数。Polynomial则由多个Term组成。Simplifier,令Parser专门进行解析工作Polynomial的子类Derivation,用于表达式求导假设现新增需求为支持三角函数,只需在Term中新增一个属性:三角函数,并在Derivation中增添对应的求导规则即可。
| Source File | Total Lines | Source Code Lines | Source Code Lines [%] | Comment Lines | Comment Lines [%] | Blank Lines | Blank Lines [%] |
|---|---|---|---|---|---|---|---|
| Add.java | 15 | 13 | 87% | 0 | 0% | 2 | 13% |
| Derivation.java | 16 | 14 | 88% | 0 | 0% | 2 | 12% |
| Function.java | 101 | 95 | 94% | 0 | 0% | 6 | 6% |
| MainClass.java | 21 | 19 | 90% | 0 | 0% | 2 | 10% |
| Mul.java | 19 | 16 | 84% | 0 | 0% | 3 | 16% |
| Parser.java | 112 | 102 | 91% | 4 | 4% | 6 | 5% |
| Polynomial.java | 78 | 70 | 90% | 1 | 1% | 7 | 9% |
| Power.java | 19 | 16 | 84% | 0 | 0% | 3 | 16% |
| Replacer.java | 50 | 45 | 90% | 0 | 0% | 5 | 10% |
| Simplifier.java | 48 | 45 | 94% | 0 | 0% | 3 | 6% |
| Sub.java | 18 | 16 | 89% | 0 | 0% | 2 | 11% |
| Term.java | 93 | 82 | 88% | 2 | 2% | 9 | 10% |
| Total: | 590 | 533 | 90% | 7 | 1% | 50 | 8% |
此处只展示复杂度最高的几个方法。Total与Average则统计了程序中所有方法.
| Method | CogC | ev(G) | iv(G) | v(G) |
|---|---|---|---|---|
| operator.Replacer.replace(String) | 10 | 4 | 4 | 6 |
| operator.Parser.findAddOrSub(String) | 13 | 4 | 6 | 9 |
| expr.Polynomial.equals(Polynomial) | 15 | 5 | 4 | 7 |
| expr.Term.toString() | 16 | 5 | 10 | 10 |
| operator.Parser.parse(String) | 16 | 7 | 6 | 7 |
| Total | 159 | 71 | 101 | 125 |
| Average | 5.13 | 2.29 | 3.26 | 4.03 |
Parser.parse用于解析表达式,流程和讨论情况较多,故复杂度较高。目前已将匹配三种最基本因子的代码提出,单独形成parseFactor方法。Term.toString是将项转化为字符串的方法,由于程序中没有设置更小的单位,故需要在此方法中考虑常数、幂函数、指数函数所有可能的情况,导致复杂度较高。| Class | OCavg | OCmax | WMC |
|---|---|---|---|
| MainClass | 2.00 | 2 | 2 |
| expr.Term | 2.83 | 10 | 17 |
| calculater.Add | 3.00 | 3 | 3 |
| calculater.Derivation | 3.00 | 3 | 3 |
| calculater.Mul | 3.00 | 3 | 3 |
| calculater.Power | 3.00 | 3 | 3 |
| calculater.Sub | 3.00 | 3 | 3 |
| expr.Polynomial | 3.60 | 7 | 18 |
| operator.Replacer | 3.67 | 6 | 11 |
| operator.Simplifier | 4.67 | 6 | 14 |
| operator.Function | 4.75 | 7 | 19 |
| operator.Parser | 5.50 | 7 | 22 |
| Total | 118 | ||
| Average | 3.81 | 5.00 | 9.83 |
爆红了5个,均值也偏高……主要是不少方法中都有if-else嵌套的情况。
Mul中没有删去合并后系数为 0 的项(Add与Sub则都有),toString中也没有针对系数为0的情况,故输出错误。当时的解决方法是直接在MUl中增补了删去合并后系数为 0 项的代码。Polynomial.addTerm中。一定程度上减少了Add、Sub和Mul中的代码量。如果从一开始就这样做,也可以避免考虑到Add和Sub,却遗漏了Mul的情况。Simplifier,令Parser专门进行解析工作。Parser.parse中将匹配三种最基本因子的代码提出,单独形成parseFactor方法。if-else嵌套较多的方法,将可以提前return的分支提前return,分支间可以提取的代码进行提取。本以为刚开学各课程强度不会太高,可以小摆一阵。不料 OO 上来就上强度,HW1 与HW2 都花费了不少时间。不过好在是又活过一个单元。
在迭代时没有经历大规模的重构,说明以 Exp_1 的设计思路为基础还是很靠谱的。三次作业完成度都较为满意,但写单元总结时却发现很多方法、类的复杂度都较高,所以又花了一定时间进行了优化(优化的过程有一种治愈强迫症的愉悦感)。对于“面向对象”这种编程思想的精髓理解得似乎不太到位,在高内聚、低耦合方面做的并不好。希望在之后的单元中能有所改善。