301
社区成员
发帖
与我相关
我的任务
分享在第一次作业中我沿用了第一次实验中的设计架构,即用Lexer类遍历字符串,然后用Parser类来解析字符串。存储结构则采用Expr,Term,Factor的体系来存储。在第一次作业中并没有意识到统一最小单元的意识,并且在化简过程中仍化为了另一颗这样的AST树,这也为第二次作业时的重构埋下了伏笔。
在第二次作业中借鉴了往届博客和讨论区的内容,开始用Poly,Mono体系来存储化简后的结果。即将解析体系的AST树转化为多项式单项式结构的AST树,这样处理在化简的过程中避免了很多问题。同时由于最小单位的统一,需要化简的各种因子处在同一层次,即同属一个类。这样使得化简中的加减乘法变得更容易处理,只需在类中封装好相应的算数运算,就能统一进行处理。
同时第二次作业加入了函数因子,我采用字符串替换的方式替换函数表达式中的参数。同时为了避免因替换先后顺序导致的错误,首先将x,y,z分别替换为a,,b,c来避免出错。在解析字符串的过程中如果遇到函数则进行字符串替换,替换完以后再解析表达式。这样通过递归调用的方式实现了函数定义时的递归操作。
第三次作业添加了求导因子以及数表达式中支持调用其他已定义的函数,由于我在第二次作业中的架构已经支持函数的递归调用,所以这次作业主要添加求导因子。由于我使用了统一最小单元来存储解析结果,所以我的求导直接在单项式上进行,即直接套用求导公式进行求导,并没有选择递归调用的方式进行求导。这样做的优点是代码改动量小,只需添加一个求导方法就能完成本次作业,但缺点是可扩展性差,如果添加了别的因子就必须进行重构。
在bug的修复过程中,我发现bug经常由于没有考虑充分。如第二次作业的强测中,我就忽略了指数有可能过大的情况。由于没有使用BigInteger数据类型来存储指数导致出错。同时我发现很多bug是因为架构问题导致,有些bug我并不知道错误出在了哪里,但当我将架构重构以后bug就神奇的消失了。这说明我的bug就是因为架构不够合理导致的。当整个架构都科学合理时,就能避免很多bug。






通过第一单元的训练我充分意识到了架构设计的重要性,正如我在bug分析中提到的。一个好的架构本身就能避免很多bug。同时我也意识到我对设计模式方面知识的空白。比如作业中的函数因子,我使用了Function类来存储定义函数以及实现函数调用,但当时我没有意识到Function类不需要创建多个对象,也就是说Function类完全可以使用单例模式来实现,但由于我对设计模式不了解,导致整个架构中很多类都和Function类耦合以实现函数的解析。这无疑增大了代码之间的耦合度,违反了“高内聚,低耦合”原则。在最初的架构设计中我也未能做到封闭性原则,如将Expr的操作却在Parser类中实现。在遇到一系列莫名其妙的bug后,我最终选择了重构,将每个类的操作封装在各个类中,实现了封闭性原则。
经过处处碰壁后我逐渐理解了老师课上传授的一些设计模式和原则的重要性,在以后的学习中,我将继续遵循这些原则和规范编码,努力设计出好的架构。
我觉得这三次作业难度分配有点问题,第一和第二次作业难度较大,第三次作业难度却非常简单。我认为应当减小第一次作业的难度让同学们更好的进入状态,同时适当加大第三次作业的难度。