BUAA-面向对象设计与构造-第一单元总结

BUAA-面向对象设计与构造-第一单元总结

作者:杨恩源 20373559

第一次作业

UML类图

 

 

采取递归下降法架构,Atompoly类用于描述多项式的单项,便于最后加和输出;因子采用Factor接口表示,解析后相乘为Term类,再进行加减运算即为表达式(Expr类)。

复杂度分析

MethodCogCev(G)iv(G)v(G)
Lexer.Lexer(String) 0 1 1 1
Lexer.getNumber() 2 1 3 3
Lexer.next() 3 2 3 4
Lexer.peek() 0 1 1 1
Lexer.prebuild1(String) 3 1 3 3
Lexer.prebuild2(String) 22 1 9 11
Lexer.prebuild3(String) 15 1 15 15
Lexer.prebuild4(String) 7 1 6 6
Lexer.prebuild5(String) 5 1 4 4
MainClass.main(String[]) 78 1 36 36
Parser.Parser(Lexer) 0 1 1 1
Parser.parseExpr() 8 1 6 6
Parser.parseFactor() 7 3 5 5
Parser.parseTerm(boolean) 1 1 2 2
expr.Atompoly.Atompoly(BigInteger, BigInteger) 0 1 1 1
expr.Atompoly.getCon() 0 1 1 1
expr.Atompoly.getExp() 0 1 1 1
expr.Atompoly.setCon(BigInteger) 0 1 1 1
expr.Atompoly.setExp(BigInteger) 0 1 1 1
expr.Expr.Expr() 0 1 1 1
expr.Expr.addTerm(Term) 4 1 3 3
expr.Expr.getSum() 0 1 1 1
expr.Number.Number(BigInteger) 0 1 1 1
expr.Number.getNum() 0 1 1 1
expr.Number.getSum() 0 1 1 1
expr.Poly.Poly() 0 1 1 1
expr.Term.Term(boolean) 0 1 1 1
expr.Term.addFactor(Factor) 6 1 5 5
expr.Term.calculate(Factor) 12 1 8 8
expr.Term.getPoly() 0 1 1 1
expr.Term.isPositive() 0 1 1 1
expr.Xexp.Xexp(BigInteger) 0 1 1 1
expr.Xexp.getExp() 0 1 1 1
expr.Xexp.getSum() 0 1 1 1

设计架构

模仿了第一次上机练习中递归下降的思路,先对字符串进行预处理,化简为标准形式,再进行解析处理,在MainClass类中输出。

优点

确定了较为完备的递归下降思路, 避免了后续迭代进行重构的问题;利用arraylist结构存储,最后统一加和输出,有利于对长度进行优化。

缺点

由于第一次作业完成的较为仓促,未能在优化、未来迭代方面全盘考虑,导致架构有些混乱、对规范因子理解不到位、预处理过于繁杂等问题。优化方面没有全面考虑表达式符号问题,导致强测未能满分。

互测体验

第一次互测之前,在强测中拿到了不错的成绩,因此互测中其他同学未能hack我的代码,同时我也没有hack到其他同学。这里体现了对其他同学代码研究不够深刻的问题。


第二次作业

UML类图

 

复杂度分析

MethodCogCev(G)iv(G)v(G)
Answer.getAnswer(HashMap<HashMap<String, BigInteger>, BigInteger>) 112 1 25 26
Function.Function(String) 3 1 4 4
Function.functionreplace(String) 109 7 40 42
Function.prebuild1(String) 3 1 3 3
Lexer.Lexer(String) 0 1 1 1
Lexer.dealingtanexp(String) 22 7 8 10
Lexer.getNumber() 2 1 3 3
Lexer.getTriangle() 6 1 3 5
Lexer.next() 4 2 4 5
Lexer.peek() 0 1 1 1
Lexer.prebuild1(String) 3 1 3 3
Lexer.prebuild2(String) 31 1 16 18
Lexer.prebuild3(String) 15 1 15 15
Lexer.prebuild4(String) 7 1 6 6
Lexer.prebuild5(String) 5 1 4 4
Lexer.prebuild6(String) 7 1 7 7
Lexer.prebuild7(String) 5 1 4 4
Lexer.sum(String) 58 7 13 15
Lexer.uvw(String) 9 1 8 8
MainClass.main(String[]) 6 1 7 7
Parser.Parser(Lexer) 0 1 1 1
Parser.parseExpr() 8 1 6 6
Parser.parseFactor() 9 4 7 7
Parser.parseTerm(boolean) 1 1 2 2
expr.Atompoly.Atompoly(BigInteger, BigInteger) 0 1 1 1
expr.Atompoly.getCon() 0 1 1 1
expr.Atompoly.getExp() 0 1 1 1
expr.Atompoly.setCon(BigInteger) 0 1 1 1
expr.Atompoly.setExp(BigInteger) 0 1 1 1
expr.Expr.Expr() 0 1 1 1
expr.Expr.Expr(HashMap<HashMap<String, BigInteger>, BigInteger>) 0 1 1 1
expr.Expr.addTerm(Term) 26 1 10 10
expr.Expr.getExp() 0 1 1 1
expr.Expr.getPoly() 0 1 1 1
expr.Expr.setExp(BigInteger) 0 1 1 1
expr.Number.Number(BigInteger) 0 1 1 1
expr.Number.getNum() 0 1 1 1
expr.Poly.Poly() 0 1 1 1
expr.Term.Term(boolean) 0 1 1 1
expr.Term.addFactor(Factor) 120 1 30 30
expr.Term.getPoly() 0 1 1 1
expr.Term.isPositive() 0 1 1 1
expr.Triangle.Triangle(String, BigInteger) 0 1 1 1
expr.Triangle.getCon() 0 1 1 1
expr.Triangle.getExp() 0 1 1 1
expr.Xexp.Xexp(BigInteger) 0 1 1 1
expr.Xexp.getExp() 0 1 1 1

设计架构

相比第一次作业,进行了部分重构和较大的架构优化;多项式改用hashmap进行存储,达到了即时求和的效果;将新增的三角函数纳入factor接口,作为因子之一参与运算。

优点
  • 将输出分离开,单独作为一个类使用,减少了代码风格上的不妥和架构上的混乱

  • 优化了atomploy的存储和运算,架构更加清晰

  • 完成了括号嵌套功能,降低了下一次迭代的工作量

缺点
  • 未能将sum和自定义纳入运算中,而是先预处理代入,不仅过于繁杂,不符合高内聚低耦合原则,还导致了hack阶段出锅和下一次迭代的重构的麻烦

互测体验
bug分析
  1. 由于代码中Term结构乘法模块中指数相加部分写错,导致强测出现WA,互测也被他人hack,应注意检查代码逻辑,多做测试。

    • 修复仅需变动一行代码的位置,侧面印证了此bug产生的不应该

  2. 当三角函数指数为0时,输出会出错,主要是Answer类输出优化逻辑出错,未做好充分测试的结果,修改对应函数if函数条件后成功修复。

hack体验

这次互测利用三角函数指数的特殊情况成功hack他人,以后做测试时应多考虑边界条件和极端情况。


第三次作业

UML类图

 

复杂度分析

MethodCogCev(G)iv(G)v(G)
MainClass.deletespace(String) 3 1 3 3
MainClass.main(String[]) 1 1 2 2
expr.Atompoly.Atompoly(BigInteger, BigInteger) 0 1 1 1
expr.Atompoly.getCon() 0 1 1 1
expr.Atompoly.getExp() 0 1 1 1
expr.Atompoly.setCon(BigInteger) 0 1 1 1
expr.Atompoly.setExp(BigInteger) 0 1 1 1
expr.Expr.Expr() 0 1 1 1
expr.Expr.Expr(HashMap<HashMap<String, BigInteger>, BigInteger>) 0 1 1 1
expr.Expr.addTerm(Term) 26 1 10 10
expr.Expr.getExp() 0 1 1 1
expr.Expr.getPoly() 0 1 1 1
expr.Expr.setExp(BigInteger) 0 1 1 1
expr.Expr.toString() 112 1 25 26
expr.Function.Function(String) 3 1 4 4
expr.Function.addAps(int, Expr) 2 1 2 2
expr.Function.calculation() 24 1 17 17
expr.Function.getFunctionHead() 0 1 1 1
expr.Function.getNumofFP() 0 1 1 1
expr.Number.Number(BigInteger) 0 1 1 1
expr.Number.getNum() 0 1 1 1
expr.Poly.Poly() 0 1 1 1
expr.Sum.Sum(BigInteger, BigInteger, String) 4 1 4 4
expr.Sum.getExpr() 0 1 1 1
expr.Term.Term(boolean) 0 1 1 1
expr.Term.addEmptyFactor(Factor) 40 1 13 13
expr.Term.addFactor(Factor) 71 1 18 18
expr.Term.getPoly() 0 1 1 1
expr.Term.isPositive() 0 1 1 1
expr.Triangle.Triangle(char, Expr, BigInteger) 3 1 3 3
expr.Triangle.getCon() 0 1 1 1
expr.Triangle.getExp() 0 1 1 1
expr.Triangle.isNum(String) 1 1 1 2
expr.Xexp.Xexp(BigInteger) 0 1 1 1
expr.Xexp.getExp() 0 1 1 1
main.Lexer.Lexer(String) 0 1 1 1
main.Lexer.dealingtanexp(String) 22 7 8 10
main.Lexer.getNumber() 2 1 3 3
main.Lexer.getPos() 0 1 1 1
main.Lexer.next() 5 2 6 7
main.Lexer.nextexpr() 7 5 3 5
main.Lexer.peek() 0 1 1 1
main.Lexer.prebuild1(String) 3 1 3 3
main.Lexer.prebuild2(String) 31 1 16 18
main.Lexer.prebuild3(String) 15 1 15 15
main.Lexer.prebuild4(String) 7 1 6 6
main.Lexer.prebuild5(String) 5 1 4 4
main.Lexer.prebuild6(String) 7 1 7 7
main.Lexer.prebuild7(String) 5 1 4 4
main.Lexer.sum(String) 58 7 13 15
main.Lexer.uvw(String) 9 1 8 8
main.Parser.Parser(Lexer) 0 1 1 1
main.Parser.getFunctions() 0 1 1 1
main.Parser.parseExpr() 8 1 6 6
main.Parser.parseFactor() 33 8 17 17
main.Parser.parseFactorExpr() 4 1 4 4
main.Parser.parseFactorSum() 6 1 5 5
main.Parser.parseFactorTriangle() 4 1 4 4
main.Parser.parseFactorXexp() 4 1 4 4
main.Parser.parseTerm(boolean) 3 1 4 4
main.Parser.setFunctions(ArrayList<Function>) 0 1 1 1

设计架构

第三次作业做的改动相对较少,主要是将sum和function纳入factor接口组成的parser运算体系中。同时也进一步优化了代码架构,调整代码风格的同时极大简化了之前繁杂的预处理。

优点
  • 递归下降的思路较为清晰,架构优化后降低了类之间的耦合度

缺点
  • 由于代码迭代中忘记及时注释掉废弃的方法,导致Sum模块新方法未能充分测试,在强测中出锅。

  • 对解析过程思考不够完善,导致自定义函数部分出现纰漏,强测WA,互测也被hack

互测体验
bug分析
  1. 和很多同学一样未考虑Sum函数中s,t的值超出int的情况,修改Sum类后修复。

  2. 自定义函数部分出错,主要是factorparse()方法中Function类进出栈顺序错误问题,调换代码顺序即可解决,这种bug在编写过程中稍微推演即可发现,下回应注意。

hack体验

这次利用了普遍性的bug,hack到了几位同学,但是对其他bug测试研究不充分,这是值得反思的,并且应在下一次作业中改进。

测试方法

参考讨论区,三次作业都采用了利用python中的sympy包对拍的方法,按照形式化表述构造数据。

总结与体会

架构设计

三次作业中,我感受到架构设计是十分重要的。良好的架构能省去相当多的重构/打补丁时间,而对架构的清晰认识能够减少代码出锅的可能性。第一单元的作业由于参考了上机练习的架构,在这方面并没有耗费太多时间,不过之后的任务未必就如此幸运了。

心得感受

寒假预习做的并不好,可以说临近开学之后,才慌忙同步开始pre和homework1的推进,在第一周同时完成了java语法基础的学习以及代码工具的使用,也导致任务推进过于紧张,不过最后还是勉强过关了第一单元,遗憾的是没有充分地探索表达式化简的可能性。希望接下来的电梯单元能再接再厉,继续深入面向对象的世界。

posted @ 2022-03-26 15:37  陶索梓  阅读(20)  评论(0编辑  收藏  举报