面向对象第三单元总结

面向对象第三单元总结

设计策略

我们JML规格能够用一定格式的语法,严谨地将方法与类的属性与功能表示出来,所以规格本身不仅仅是要求,更是对方法与类的设计的线索与提示。

通过规格描述,我们可以大致了解到那些成员属性是需要修改的,方法可能需要怎样的数据结构;可以通过requires/ensures,我们可以进行方法处理流程的精确分类,能够针对不同的前置条件分门别类准确实现处理。

而在依据规格进行设计时,设计者的个人理解也至关重要。规格描述虽然严谨,但及其刻板而抽象,只针对规格进行模式化设计,很容易缺乏工程整体系统上的把握,缺乏对方法功能本质的理解,无法进行全局构思,难以灵活应对处理各种需求。所以,在依据规格设计时,我们需要对工程整体有所把握,根据业务需求,理解各个类与方法的本质功能以及各方法的调用关系等,在此基础之上便能更加轻松地理解方法规格的意义,并在满足规格要求的前提下构建自己需要的辅助性类、方法与数据结构,来优化部分方法与整个工程的性能。

测试方法

本单元的测试,形式上依据各个指令搭配的形式来设计测试样例。原则逻辑上,需要依据规格,对各个方法的normal_behavior与exceptional_behavior的各种情况进行覆盖测试。

整体上对于所有指令均需进行混合测试,重点针对一些涉及复杂算法的指令,如qbs,sim等,进行更为全面覆盖的测试,并着重对一些极端数据进行测试。

但在实际测试过程中,人为设计测试样例往往难以实现全面覆盖,在对本单元三次作业进行测试时,均出现由于数据体量过小而导致部分bug未被测出。以及,由于未进行超大型数据集测试,导致强测过程中出现运行时间过长的问题。

容器使用

本单元作业在初步完成时,容器主要选择均为ArrayList。该容器操作简单,功能直接,可以适应各种业务需求,可拓展性强,可以作为基础算法的模板化容器,在较为简单的数据中使用方便。但对于大型数据集,其功能的简易型难以适应更复杂的算法与高级业务需求。

而在优化过程中,针对大型数据集需要频繁根据ID访问成员的问题,使用HashMap容器能够很好地建立起ID与成员的映射关系,更好地适应工程规模,能够对性能与代码量进行优化,大大增加了代码可读性,降低维护成本。

性能问题

本单元作业在性能方面有以下几个问题及原因较为突出:

1.容器使用问题。如“容器选择”条目所示,初期使用的经典ArrayList无法适应后期算法,需要针对需求更换如HashMap等更高效更合适的容器。

2.图论算法问题。在第三次作业中,未能将最短路径的算法进行优化以适应需求,采用了最原初的算法,并生硬地套用在了程序当中,没有精细地设计优化,重复利用,极大降低了重复性、规律性访问最短路径的效率。

3.动态计数问题。第二次作业关于query_block_sum的算法,采用了一种动态计数的策略,利用分支之间的连通关系(每增加一个节点便增加一个分支,每两个不属于同一分支的节点建立联系后便减少一个分支)的方法,虽然逻辑思路简单,容易实现,但需要频繁地调用isCircle函数来判断两个Person的连通性,导致在频繁使用ar指令建立联系时,性能及差。

4.数据样例问题。在“测试方法”条目提到,由于本地测试没有针对性能构造指令量极大的数据样例,导致实际测试中暴露出的性能问题未能第一时间发现并优化。

架构设计

MyPerson:整个关系网(MyNetwork)的节点,整个图的结构基础。

MyMessage:消息类,MyNoticeMessage, MyEmojiMessage, MyRedEnvelope的父类,MyPerson之间传递的消息载体。

MyGroup:部分MyPeron的集合,是整个MyNetwork节点集合的子集,部分MyMessage发送的限定范围。

MyNetwork:关系网,MyPerson的全集,一切消息、数据与指令均建立在此类构建的抽象平台之上。

Graph:图类,将MyNetwork抽象的节点与边,以及图论涉及的算法均包含在次结构类中。

MainGlass:主类。

以及一切继承自Exception的异常类。

posted @ 2021-06-01 19:11  月下天弦  阅读(45)  评论(0)    收藏  举报