大二下的第一个月就要结束了,OO的第一单元也结束了,因此在这里总结一下我的OO的第一单元的情况。
总体
第一单元有三次(不计寒假pre)作业,分别为:多项式求导,带有幂函数、三角函数的表达式求导 和 带嵌套的表达式求导。
我三次作业的结构都不完全一样,其中第一次和后两次完全不一样,第三次基本沿袭第二次。下面,我review一下我每次的结构。
结构
第一次
结构
第一次的结构比较简单,基本就是使用HashMap记录每个次幂的系数,然后Poly求导时调用Term的求导方法即可。
耦合度
class | OCavg | WMC |
---|---|---|
InputFormatWrong | 1.0 | 2.0 |
Poly | 3.5 | 21.0 |
Term | 2.3 | 23.0 |
TermAddPowDifferent | 1.0 | 3.0 |
Total | 49.0 | |
Average | 2.3333333333333335 | 12.25 |
第二次
第二次作业我的总体结构分为了三层:
- Expression
- Term
- Factor
- PowFunc
- TriFunc
- Constant
其中,Factor是一个抽象类(现在想来,使用接口更好)
每一层,使用ArrayList记录下一层的引用。
加法求导直接调用下一层即可。
乘法求导使用链式法则。
输出部分,为了拓展性,我使用专门的Outputer类进行的输出,里面使用了Quad和Triad两个类进行优化,这两个类重写了equals,hashCode,comparaTo等方法,使用hashMap合并。
耦合度
class | OCavg | WMC |
---|---|---|
Expression | 2.3076923076923075 | 30.0 |
Factor | 1.0 | 3.0 |
InputFormatWrongException | 1.0 | 2.0 |
Main | 2.0 | 2.0 |
Number | 1.1428571428571428 | 8.0 |
Outputer | 7.25 | 29.0 |
PowFunc | 1.5714285714285714 | 11.0 |
Quad | 1.9166666666666667 | 23.0 |
Term | 2.25 | 27.0 |
Triad | 2.0 | 16.0 |
TriFunc | 2.125 | 17.0 |
Total | 168.0 | |
Average | 2.1818181818181817 | 14.0 |
这次作业我专门花了大量时间设计了结构,因此整体耦合度相比第一次好看了许多。不是很好的时Outputer类,这里有大量的优化代码,优化代码写的不够优美,因此我还需要更多练习。
第三次
结构
第三次作业基本继承了我第二次的结构
我的总体结构分为了三层:
- Expression
- Term
- Factor
- PowFunc
- TriFunc
- Constant
- ExpFactor
其中,Factor是一个接口
每一层,使用ArrayList记录下一层的引用。
TriFUnc有一个Term的引用
ExpFac有一个Exp的引用
综上,我的结构基本符合文法。
加法求导直接调用下一层即可。
乘法求导使用链式法则。
输出部分,我重写了toString方法
耦合度分析
method | ev(G) | iv(G) | v(G) |
---|---|---|---|
Builder.build(String) | 3.0 | 2.0 | 4.0 |
Builder.readExp(String,ArrayList) | 4.0 | 4.0 | 7.0 |
Builder.readFactor(String,ArrayList) | 9.0 | 7.0 | 10.0 |
Builder.readTerm(String,ArrayList,BigInteger) | 4.0 | 6.0 | 7.0 |
Builder.triMatch(String,ArrayList,Matcher,int) | 4.0 | 2.0 | 4.0 |
Constant.calcDerivative() | 1.0 | 1.0 | 1.0 |
Constant.Constant() | 1.0 | 1.0 | 1.0 |
Constant.Constant(BigInteger) | 1.0 | 1.0 | 1.0 |
Constant.Constant(String) | 1.0 | 1.0 | 1.0 |
Constant.getValue() | 1.0 | 1.0 | 1.0 |
Constant.toString() | 2.0 | 1.0 | 2.0 |
ExpFac.calcDerivative() | 1.0 | 1.0 | 1.0 |
ExpFac.ExpFac(Expression) | 1.0 | 1.0 | 1.0 |
ExpFac.getExp() | 1.0 | 1.0 | 1.0 |
ExpFac.isIn(String) | 5.0 | 4.0 | 8.0 |
ExpFac.toString() | 3.0 | 2.0 | 4.0 |
Expression.add(Expression) | 1.0 | 1.0 | 1.0 |
Expression.add(Term) | 1.0 | 1.0 | 1.0 |
Expression.addTerm(Term) | 1.0 | 1.0 | 1.0 |
Expression.calcDerivative() | 1.0 | 2.0 | 2.0 |
Expression.Expression() | 1.0 | 1.0 | 1.0 |
Expression.Expression(ArrayList) | 1.0 | 2.0 | 2.0 |
Expression.Expression(Term) | 1.0 | 1.0 | 1.0 |
Expression.merged() | 1.0 | 1.0 | 1.0 |
Expression.multiply(Expression) | 1.0 | 1.0 | 1.0 |
Expression.multiply(Term) | 1.0 | 1.0 | 1.0 |
Expression.toString() | 1.0 | 5.0 | 7.0 |
InputFormatWrongException.getSituation() | 1.0 | 1.0 | 1.0 |
InputFormatWrongException.InputFormatWrongException(String) | 1.0 | 1.0 | 1.0 |
Main.main(String[]) | 2.0 | 3.0 | 4.0 |
PowFunc.calcDerivative() | 1.0 | 1.0 | 1.0 |
PowFunc.getPow() | 1.0 | 1.0 | 1.0 |
PowFunc.PowFunc() | 1.0 | 1.0 | 1.0 |
PowFunc.PowFunc(BigInteger) | 1.0 | 1.0 | 1.0 |
PowFunc.toString() | 3.0 | 3.0 | 3.0 |
Quad.compareTo(Quad) | 3.0 | 3.0 | 3.0 |
Quad.equals(Object) | 6.0 | 2.0 | 6.0 |
Quad.getArr() | 1.0 | 1.0 | 1.0 |
Quad.getFirst() | 1.0 | 1.0 | 1.0 |
Quad.getForth() | 1.0 | 1.0 | 1.0 |
Quad.getSecond() | 1.0 | 1.0 | 1.0 |
Quad.getThird() | 1.0 | 1.0 | 1.0 |
Quad.hashCode() | 1.0 | 2.0 | 2.0 |
Quad.merge(Quad) | 1.0 | 2.0 | 2.0 |
Quad.Quad(BigInteger,BigInteger,BigInteger,BigInteger) | 1.0 | 1.0 | 1.0 |
Quad.Quad(BigInteger,Triad) | 1.0 | 1.0 | 1.0 |
Quad.Quad(BigInteger[]) | 2.0 | 1.0 | 3.0 |
Term.addFactor(Factor) | 1.0 | 1.0 | 1.0 |
Term.calcDerivative() | 1.0 | 2.0 | 2.0 |
Term.multiply(Factor) | 1.0 | 1.0 | 1.0 |
Term.multiply(Term) | 1.0 | 1.0 | 1.0 |
Term.Term() | 1.0 | 1.0 | 1.0 |
Term.Term(ArrayList) | 1.0 | 2.0 | 2.0 |
Term.Term(Factor) | 1.0 | 1.0 | 1.0 |
Term.toString() | 1.0 | 3.0 | 5.0 |
Triad.equals(Object) | 6.0 | 2.0 | 6.0 |
Triad.getArr() | 1.0 | 1.0 | 1.0 |
Triad.getFisrt() | 1.0 | 1.0 | 1.0 |
Triad.getSecond() | 1.0 | 1.0 | 1.0 |
Triad.getThird() | 1.0 | 1.0 | 1.0 |
Triad.hashCode() | 1.0 | 2.0 | 2.0 |
Triad.Triad(BigInteger,BigInteger,BigInteger) | 1.0 | 1.0 | 1.0 |
Triad.Triad(BigInteger[]) | 2.0 | 1.0 | 3.0 |
TriFunc.calcDerivative() | 1.0 | 2.0 | 2.0 |
TriFunc.getPow() | 1.0 | 1.0 | 1.0 |
TriFunc.getType() | 1.0 | 1.0 | 1.0 |
TriFunc.getVal() | 1.0 | 1.0 | 1.0 |
TriFunc.toString() | 3.0 | 3.0 | 5.0 |
TriFunc.TriFunc(int,Factor,BigInteger) | 1.0 | 1.0 | 1.0 |
Total | 114.0 | 113.0 | 150.0 |
Average | 1.6521739130434783 | 1.6376811594202898 | 2.1739130434782608 |
class | OCavg | WMC |
---|---|---|
Builder | 6.4 | 32.0 |
Constant | 1.1666666666666667 | 7.0 |
ExpFac | 2.8 | 14.0 |
Expression | 1.6363636363636365 | 18.0 |
InputFormatWrongException | 1.0 | 2.0 |
Main | 2.0 | 2.0 |
PowFunc | 1.4 | 7.0 |
Term | 1.75 | 14.0 |
TriFunc | 1.8333333333333333 | 11.0 |
Total | 146.0 | |
Average | 2.1159420289855073 | 12.166666666666666 |
可以看出,我的builder写的不是很尽人意,不过由于这是读入部分,内部耦合度的确会很高。综合来看,这次的情况比上次好了许多,我也的确感觉自己的结构优美了、“面向对象”了很多。
BUG
我没有在公测和互测中被发现BUG
从中我大概总结如下:
- 设计结构时让结构优美
- 写代码时认真思考
- 写代码时符合标准,代码风格需要优美
- 写完后测试所有样例
- 认真手动构造极限的样例
- 使用自动化测试测试自己的代码(跑一天以上)
- ……
同时,我也看了其他同学的代码,发现了一些印象深刻的代码,大概如下
- 优化写错
- 个人认为,如果结构设计的够好,优化部分也是可以写起来很简单的。比如如果写足了表达式的乘、加等方法,在优化的时候调用就好,切忌面向过程地优化!
- 读入写错
- 读入是一个十分值得测试的部分,交作业前在进行测试的时候,一定要做到充分的,全面的测试。
关于创建模式
创建模式看起来十分深奥,在我简单的理解起来,大概是一个在选择创建一个父类的多个子类的时候,让子类的选择交给一个的一个方法。这样,可以降低代码的耦合度。
就是说,我的一个类的判断,只负责判断一层。
这次,我在对象创建的时候,我专门实现了一个builder类,builder类内有三个方法,分别识别Exp,Term,Factor。现在看起来,我可以把这三个方法拆开,分别识别一个类,这样降低耦合度。
感想
第一个月刚刚过去,表达式求值也是我写的第一个系统的java的工程。可能目前我对面向对象和java的理解还不够深入,但我相信在不断的OO课程的学习和练习中,对这方面的理解会越来越深入。
感谢为这门课程付出的老师和助教们。