OOP 第四章博客总结
本单元两次作业架构设计
这两次作业全部都是面向需求(指导书)设计的,以更方便实现指导书上限定的功能为目标,所以并没有完全对 Uml 树状结构进行建模。而且由于两次作业之间只是增加需求没有对已有的架构进行重构,所以在此只展示最后一次作业的架构。
第一次作业的架构设计
第一次作业只涉及 UmlInteraction、ClassManager、Operation 三个类以及一个 Main 类。由于第一次作业只涉及类图的查询,而类图中关键元素便是类、接口、类和接口中的操作、类的属性、关系这些。
对类和接口,我进行了统一地建模,用 ClassManager 来表征(虽然类和接口有所区别,但都可以整合到一个模型上)。ClassManager 负责记下这个类\接口的名字、包含的属性、操作以及其的继承、关联、实现等关系。对于类的属性、操作使用 ArrayList 进行组织管理,对于关系采用 ArrayList 记录下这个类的对端类的 id 来实现(即有点像链表法记录图的结构)。
对于类和接口中的操作,也进行了单独建模。Operation 负责记录下该操作的名字、可见性、以及参数、是否有返回值等信息。
对于类的属性,并没有为其单独建模是因为 UmlAttirbute 不再包含其他元素,其自身便是最小元素,所以直接使用 UmlAttribute 即可不需要为其单独建模。
最后 UmlInteraction 只需要负责创建维护 ClassManager 并借由 ClassManager 提供的方法实现指导书上的查询需求即可。
第二次作业的架构设计
第二次作业由于新增了状态图与顺序图,便也新增了 StateMachine、Sequence 与之对应建模。UmlGenralInteraction 继承上次的 UmlInteraction,先将所有 UmlElements 扔给父亲构造器解析,再将属于状态图的元素、属于顺序图的元素,分别创建一个 StateMachine 或 Sequence 实例然后扔进去就可以了。最后对于查询只需要使用 StateMachine 和 Sequence 提供的方法进行即可。
对于规则检查,第一个规则简单的在 ClassManager 中实现一个自查方法,然后在 UmlGeneralInteraction 中只需要对每一个 ClassManager 调用这个方法就可以了。第二个规则就是图的遍历找有没有环,单独创建了一个方法类 GraphCal,只需要调用其中实现的方法(无脑 dfs 遍历)就可以了。第三个规则,简单的使用广度优先遍历,看有没有重复继承就可以了。
架构设计及 OO 方法理解的演进
架构设计这一方面最大的进步就是,拿到一个问题会去思考这个问题中有几个角色(需要建模几个类),而不是这个问题应该分几步完成。虽然在问题规模比较小的时候,按分几步走的思路确实能较为简单地解决,但是对于复杂一点的问题,按照面向对象的思路确实好解决的多了。这个问题中会涉及到哪些角色,他们的职责是什么,我们只需要明确这些,然后把任务分配下去,每个类自己实现自己的职责(这里可能会需要进行二次划分小类)。这样的解决方式更贴近于现实生活中的分工体系,也利于人们理解。
其次感受最深的是,命令式编程。类与类之间的交互不应该涉及太深,一个类需要另一个类干活,并不应该把另一个类的属性、方法拿过来,然后自己去实现,而是应该以命令的口吻“我要你做这个,最后把结果告诉我就可以了”。通过这样的方式去设计,才能更好的降低类与类之间的耦合程度。
除此之外,对于 OO 的进一步了解,就是对于 OO 设计 6 大原则以及设计模式的学习,诸如:工厂模式、代理模式等等。虽然很多设计模式、设计理念在我们作业中很难得到应用,因为作业的问题规模还是较小的,但是提前了解到他们,有助于我对 OO 的理解更进一步。
测试理解与实践的演进
对于测试这一方面进步最大的是,了解到了什么是单元测试以及怎么进行单元测试。通过撰写 Junit 测试代码进行单元针对性的测试,确实能比较精准地测试每一个方法的实现是不是跟预期有所区别。
除此之外,还进一步实践了使用 python 搭建数据生成器与评测机。数据生成器最主要的还是依赖于根据正则表达式的随机生成函数,而自己写的评测机就是一个简单的对拍器。
PS:OO 课程充分证明了我是个么得耐心测试的懒子。
对于实践方面,在完成作业的过程中,越来越能够花更多的时间去分析需求,罗列所需要完成指导书上需求需要实现哪些东西或者记录哪些输入信息,并思考以什么样的数据结构去组织这些信息,以及对于特殊情况的考虑与注意。而这种对于分析需求的时间投入的历次加大,也使得我编程代码越来越轻松、条理越来越明晰。这是我在作业实践方面最大的进步。
课程的收获
本次课程最大的收获还是在于之前提到的对于架构设计以及面向对象设计思想的学习以及对其的应用实践。这让我感觉自己第一次切实体会到了一些现在行业做项目的时候会遵循的一些原则,让自己从大一那种简单无脑莽代码逻辑实现变成会去考虑这样写是否合理(美)、是否易于维护以及 debug,有了一种对于代码美学的追求。
而且这个课程还让我第一次编写了会去考虑用户非法输入等涉及鲁棒性的程序,这是在之前的学习中没有感受到的。切实亲手去解决用户的非法输入让我意识到在实际项目开发的时候,用户往往并不会按照你的期望进行输入交互,你需要考虑到这一点进行防备以及必要的用户引导。
改进建议
- 建议定下来时间线就不要轻易改动了,因为习惯了这个时间线,突然改时间,会严重打乱自身的安排,而且会影响的人身心不宁(就是有点无所事事的感觉),本来周五晚上看指导书,周末就可以肝完,可是时间后移,周五和周末就不知道该干啥了(空虚难受)。
- 个人感觉,最后一个单元的作业并没有帮助我对 Uml 的理解更进一步。单纯解析 Uml,确实让人对 Uml 树形结构有很深的映像,但是对于其中的概念理解还是不很深刻(就像聚合和组合之间的异同,我还是记不到,每次都要上网查)。不过,课上的实验都很棒,亲手去设计一个类图、或者是找类图、状态图、顺序图之间不自洽的地方,都很能够帮助我们理解到 Uml 的核心理念。个人感觉还是让学生自行设计 Uml 类图等,然后根据自己的设计去实现会能够让人体会到一个完整的设计流程,比如课上实验就是设计 Uml 类图,然后课下作业就是切实的去实现自己的设计(虽然不好去检查类图和代码实现是否匹配,但是这样的 push 能够让想要这么做的同学得到很好的锻炼)。如果能够在二者之间加上助教或者老师对学生的设计提出建议、点评就更好了。
- 实验课结束之后,可以根据实验内容提供一些参考答案(某些实验有必要的感觉)。比如最后两次 Uml 的实验课,课后都可以建一个帖子,公布一下参考答案,让我们意识到老师们是怎么想的,有助于对实验内容的理解。
- 关于 jml 那一单元,作业需求仍然不太需要看规格就能完成,毕竟看指导书指令的名字很多需求我们就能够大概掌握了,所以感觉这一单元有点鸡肋。因为实际上,不仅是我,还有我身边的一些同学,根本就没有怎么去看规格就完成了作业,因此 jml 的意义就不明了(可能是由于我们实现的功能过于普通)。但是个人觉得学习 jml 的意义也不太大,在设计之中对于分工只需要规定好相应的接口,然后人们就可以自行工作,而对于边际条件的表述也可以通过注释或者文档的方式很明确的说明清楚而没必要依靠复杂并不是所有人都懂的 jml 规范。