第四单元及课程总结
第四单元架构设计
写在前面
本单元作业是写一个UML类图、状态图和时序图的解析器。由于作业采取黑箱测试,并且我对如何解析UNL图并没有十分明确的认识,因此在实现过程中完全是通过给出的样例的输入和输出来完成对方法的实现。
架构设计
类图
类图中包含了类、属性、方法、参数、继承、关联、接口等多种组成成分。
对于类,我首先建立了一个新的MyClass来存储跟这个类(接口)相关的组成成分(Fatherid或者reference是该类(接口)的),并且建立hash图idClass以便我能够通过id来对它进行索引,这样防止了出现类重复导致的bug。
我通过设置一个单独的int变量对类图中类的数量进行统计。这样可以很方便的把可能出现的同名类也进行计数。
同时,由于查询指令传入的参数大部分是对象的名字,我建立了通过名字来索引类和接口的hash图nameClass,这样可以让我在无异常抛出时的操作变得十分方便,也是我作业中最重要的操作:通过名字获取id,在再通过id索引到相应的myclass。
对于其他的组成成分,我也在MyUmlGeneralInteraction设置了相应的利用id索引到对象的hash图。这些组成成分都可以利用Fatherid或者reference来索引到相应的类。
下图展示了MyClass类中的数据的组织形式。
状态图和时序图
在完成类图的构建以后,这两个图的解析相对简单,在实现过程中,只需要把UmlInteraction以及UmlStateMachine放在类图中UmlClass相同的重要的位置即可即可。
有效性检查
在有效性检查中,难点在于对有向图的操作,我借助Stack,使用了拓扑算法来检查是否有循环继承,使用MyClass类中的son和father等数组来检查是否有重复继承。
不足
由于实现的过程中,只是为了达到预想的输出,因此,对架构的完整性和系统性并没有进行全面的维护,例如对于类MyClass,理论上应当要把与该类相关的组成成分全部加入,并设置相应的访问方法,但是我在满足需求以后就没有继续将其完善了。
同时,为了满足代码风格的需要,我新建了3个类来分别存储类图、时序图、状态图的方法,只需要在MyUmlGeneralInteraction类中的构造方法传入相应的数据即可。
架构与理解演进
¥第一次作业中,是利用栈和有限状态机来实现对多项式的求导,但是在实现的过程中,我并没有使用java中现成Stack来对数据进行组织,而是使用ArrayList,造轮子的行为让我在实现过程中出现了许多错误,甚至对自己的架构产生怀疑。
¥第二次作业中,由于受到课上实现的启发,我很轻松地了解了生产者、调度器、消费者的模型,较好地完成了作业。对我来说,死锁才是这次作业中的重中之重,为了避免死锁同时兼顾效率,一般情况下我只是在写入的时候加锁,而没有在读去的时候加锁。
¥第三次作业中,理解jml以后可以轻松的了解到这次作业考察的是对图的操作,我在addRelation中做了相当多的工作以完成对图的构建,是其他查询方法复杂度降低,,但是O(n方)的复杂度并不能满足性能的要求。
¥第四次作业中,考察对uml图的解析,这次作业主要让我思考的是如何将Uml图中的元素组织和联系起来,有效性检验过后的类图看上去就像一个倒立的多叉树,但是构造多叉树很麻烦,索引次数也比较多,因此我只是采用HashMap来组织。
测试与实践
在这一方面,我没有倾注很多的时间,第一单元,我尝试在给出的数据上稍作改动。但是之后的单元,我构造数据却又无法给出正确的输出,尤其是最后两次黑箱的作业,我对各种方法的工作机制没有全面的了解。所以在测试方面,收获甚微。
课程收获
课程收获在于对每次作业的思考,每当我想出一些能够实现的与众不同的方法,都是一件特别有成就感的事情。当然,在需求不断扩展的构成中,我也主动或者被动的去了解java中的方法和技巧。每一次作业都能让我感受到我有所进步,也让我逐渐意识到什么是面向对象。老师经常说,后面的作业并不十分要求算法,但是在完成作业的过程中,我发现优秀的架构设计和算法是分不开的,都是需要花费时间考虑的问题。在一次次迭代开发中,我也收获了一些工程化的方法,也更加重视如何在实际生活中应用代码的思想以及性能的问题。
具体的改进建议
¥关于bug修复,有时候对代码进行了修改行数过多,导致西药提交合并修复,但是提交合并修复后需要审核以后才能继续提交,为了防止出现修一次bug等一次审核的情况出现。我一般是通过所有测试点以后再提交,这似乎不太符合课程组的要求。可以考虑对修复bug环节的机制进行修改。
¥关于训练栏目,希望可以不用设置截止时间,可能会提高同学们的参与度。
¥第二单元第一次作业,如果没有课上实验的代码,我很难轻松的完成作业,可以考虑在预习环节加上一些简单的多线程作业题,帮助同学们提前认识一下多线程。