301
社区成员
发帖
与我相关
我的任务
分享表1 第三次作业规模度量
|
类名 |
成员变量 |
成员函数 |
成员函数代码规模 |
控制分支规模 |
类总规模 |
|
Main |
/ |
/ |
<60 |
0 |
<60 |
|
FuncMap |
容器:1 |
添加新函数:1 代入:4 |
<60 |
8 |
~120 |
|
Func |
基础类型:3 |
解析新函数:1 代入:1 |
<60 |
0 |
<60 |
|
Expression |
VarfMap:1 基础类型:2 |
解析:2 输出:1 |
<60 |
2 |
<60 |
|
Term |
VarfMap:1 基础类型:2 |
解析:2 |
<60 |
2 |
<60 |
|
Factor |
VarfMap:1 基础类型:2 |
解析:2 |
<60 |
5 |
<60 |
|
VarfMap |
容器:1 |
构造:2 运算:5 hash相关:2 输出:6 |
<60 |
32 |
~200 |
|
Varf |
VarfMap:1 基础类型:2 BigInteger:1 |
构造:2 解析:6 运算:2 hash相关:2 |
<60 |
15 |
~150 |
|
Expf |
VarfMap:1 基础类型:2 |
解析:2 |
<60 |
3 |
<60 |
|
Drvf |
VarfMap:1 基础类型:2 |
解析:2 |
<60 |
0 |
<60 |
|
Conf |
BigInteger:1 基础类型:2 |
解析:2 |
<60 |
2 |
<60 |
|
Intc |
BigInteger:1 基础类型:2 |
解析:2 |
<60 |
2 |
<60 |
使用IDEA代码复杂度检查插件MetricReloaded,可以得到方法和类的复杂度,下面的分析结果仅节选需要重构优化的部分。
表2 方法复杂度含义
|
复杂度名 |
含义 |
范围 |
推荐值 |
|
认知复杂度(Cogc) |
用于衡量阅读和理解一个成员函数的难度,函数越难以理解,认知复杂度越高 |
[0, 30] |
[0, 15] |
|
基本圆复杂度(ev(G)) |
用于衡量一个成员函数非结构化程度,成员函数中非结构的部分越多,基本圆复杂度越大 |
[1, 12] |
[1, 3] |
|
设计复杂度(iv(G)) |
用于衡量成员函数之间的调用关系,一个成员函数内调用其他成员函数越多,成员函数之间的耦合度就越高,设计复杂度越大 |
[1, 9] |
[1, 8] |
|
圆复杂度(v(G)) |
用于衡量一个成员函数控制的复杂程度,成员函数中的分支/循环控制越多,圆复杂度越大 |
[1, 12] |
[1, 10] |
表3 第三次作业分析结构(节选)
|
方法 |
Cogc |
ev(G) |
iv(G) |
v(G) |
|
VarfMap.printStr() |
18.0 |
3.0 |
8.0 |
8.0 |
|
Varf.equals(Object) |
9.0 |
5.0 |
5.0 |
9.0 |
|
VarfMap.equals(VarfMap) |
8.0 |
5.0 |
4.0 |
5.0 |
|
VarfMap.isSingle() |
11.0 |
5.0 |
7.0 |
7.0 |
通过分析可以看出,方法VarfMap.printStr()由于适用过多分支控制导致该方法认知复杂度过高;剩下3个方法也是因为出现层数和嵌套数较多的分支控制,导致方法的基本圆复杂度较高。
图1 第三次作业类图
为不同的运算单元(表达式、项、因子)引入对应类,并通过函数“analysis()”将运算单元解析为相同格式——“X^指数”——的因子,其中因子的系数就是该种因子的数量。同时,通过采用类似“递归下降”的方法解析嵌套括号。
通过采用字符串替换的方式实现函数代入功能。同时,由于指数函数的引入,解析后的因子格式扩展为“X^X指数*EXP(EXP指数)”。
通过引入函数“derive()”对解析后的因子集进行求导运算。
修正了int溢出引发的bug,采用BigInteger。
修正了字符串直接替换引发的代入bug,在字符串替换前,将函数中的x、y、z替换为a、b、c。
修正了exp(x)^0 = exp(x + 0) = exp(x)引发的运算bug,直接强制使exp(x)^0 = 1
修正了嵌套函数代入不检查引发的代入bug,在完成一次函数代入后,检查是否还有函数名。
通过HashMap优化因子的合并:修改hashcode()函数和equals()函数,将对象不同但数据相同的因子进行合并。
优化输出:根据题目要求,将部分形如“1*x”、“exp(0)”的优化为“x”、“1”。
复习了面向对象开发的概念和基本流程。
认真完成每一次面向对象开发作业。