zoukankan      html  css  js  c++  java
  • OO第四单元总结

    一、作业架构设计

    (1)第一次作业

     需求分析

      实现实现一个UML类图解析器,能够完成对类图的相关信息的查询。

     设计思路

    • 将官方包解析出来的UmlElement类重新进行封装,根据不同类型的数据设置不同的参数和方法,继承一个共同的父类完成统一管理。
    • 使用实现的数据管理类还原树结构并建立相关查询索引,实现所需的各项功能。

     类图及相关类说明

      UmlData:作为所有需要管理的数据类型的父类。

      UmlClassData:管理UmlClass的相关数据,包含原始的UmlClass以及操作、属性、实现的接口、关联的类的信息。

      UmlOperData:管理UmlOperation的相关数据,包含原始的UmlOperation以及参数列表、可见性、返回值的信息。

      UmlInterData:管理UmlInterface的相关数据,包含原始的UmlInterface以及继承的父类的信息。

     实现细节

    • 大部分查询功能只需要在建立好从名称到数据的目录的基础上,通过直接查找或者是一次遍历即可实现,如查询操作和属性的数目以及查询顶级父类等。
    • 对于查询实现的接口集合,由于接口可以多继承的特点,需要进行遍历和递归,在递归时使用缓存可避免多次查询提高效率。

    (2)第二次作业

        需求分析

      在第一次作业的基础上,对UML解析器的功能进行扩展,实现对状态图和顺序图的解析以及对模型的合法性检查。

     设计思路

    • 对状态图和顺序图重新进行封装,形成类似于第一次作业中的数据结构,继承UmlData类。
    • 对状态图和顺序图建立额外的索引,按照和类图相似的形式进行统计和查询。
    • 实现不同功能的接口按顺序继承上一级,实现功能的分离,例如我最上层的MyUmlStandardPreCheck类实现模型检查,MyUmlClassModelInteraction类继承自前者并实现第一次作业的功能,MyUmlStaColInteraction类继承自前者并实现对顺序图和状态图的检查,MyUmlGeneralInteraction类继承自前者并在Main函数中被实例化。

     类图及相关类说明

      UmlSmData:管理UmlStateMachine的数据,包含原始的UmlStateMachine和下层的Region信息。

      UmlRegionData:管理UmlRegion的数据,包含原始的UmlRegion以及各种状态和迁移的信息。

      UmlInteractData:管理UmlInteraction的数据,包含原始的UmlInteraction以及Lifeline和Message的信息。

     实现细节

    • 在实现检查R002规则的功能时,需要求有向图的强联通分量,我是直接采用的DFS的方式实现的;检查R003规则,我采用了递归和缓存的方法(和第一次作业求实现接口列表的方法大致相同)。
    • 对于求状态图的可达状态方法,由于图中可能存在环路,在递归时需要注意边界条件的判断,因此也不能使用缓存提高效率(个人没想到好的办法),需要将所有可能的起始点遍历求一遍。

    二、架构设计及OO方法理解

    (1)第一单元:多项式求导

      个人认为,第一单元作业的目的是让同学们熟悉java语法和常用库的使用实现抽象化设计、初步尝试面向对象架构多项式求导首先就要根据不同的规则将每一项提取出来,在这个过程中用到了正则表达式的相关库。抽象化设计考虑的是将需求抽象化,根据一致性把使用的算法和数据结构进行封装使其能适应不同类型的输入数据。例如在表达式求导中,根据求导链式法则,将表达式抽象为一颗表达式树的结构能很好地完成求导的功能,这样三次作业就可以在同一种结构上进行功能扩展实现(我就没有考虑到这一点导致第三次作业大规模重构)。在架构设计上,将表达式行为(分项、求导)和项的行为(解析、求导)进行分离,不同类型的项继承自同一个父类便于管理,实现模块化的结构,降低了耦合度。总而言之,在第一单元中我对面向对象架构设计有了初步理解。

    (2)第二单元:多线程电梯

      第二单元的作业是多线程电梯,这一单元主要内容是多线程编程、设计模式以及电梯调度算法。在本单元中我们初步接触到了多线程编程。在Java编程中,线程的实现方法主要有继承Thread和实现Runnable接口两类。在课堂上,我了解到了常用的多线程模型(生产者-消费者模型和托盘模型),实际上电梯问题就可以抽象为生产者-消费者问题。如何保证线程安全问题是多线程中需要考虑的重要问题,在Java中我们可以通过wait()和notify()以及加锁的方法实现对共享数据的互斥和同步访问。多线程编程更需要我们对代码的架构进行正确设计以保证正确性和可拓展性,我们也学习到了一些设计模式的知识(例如工厂模式、单例模式)。另外,电梯调度算法也是本单元中比较重要的部分,在本单元第二次和第三次作业中我使用了捎带算法和Look算法。

    (3)第三单元:JML规格化设计

      第三单元是基于JML的规格化设计,本单元的重点是JML语言的学习契约式编程的架构设计,在给定JML设计需求的前提下最终实现地铁图的计算问题。JML语言是描述规格需求的一门语言,相较于自然语言它的准确性更好。本单元的设计模式也和之前两单元有很大不同,我们是根据给定好的JML需求进行编程(契约式编程),在设计中基本不需要自己考虑架构的问题,填写的大部分是对方法的具体实现。我认为本单元也是课程组给我们的一个架构范本,官方包通过三次作业给出的规格告诉我们如何从简单图扩展到地铁图的计算,根据任务需求实现抽象化、层次化的设计,以及各个功能方法如何实现高内聚低耦合。另外,本单元的第三次任务需要我们对图重构处理,将其化为最短路问题进行解决。

    (4)第四单元:UML图解析

      第四单元的内容是UML图解析,我认为本单元是对课程前几单元架构设计的综合实践。尽管涉及到的各种算法并不复杂,但是UML图的特点使本单元的代码量和复杂度相对于之前的作业大了不少,需要我们学习的东西也是最多的,也要自己考虑架构设计。针对于不同的UML类图、状态图、顺序图元素,我参照官方包的方法,构造了同一个类的不同子类进行数据管理,实现了数据管理的层次化的设计。在功能实现上,我将规则检查、类图查询、顺序图和状态图的查询分别放到不同层次的类中实现,并使用继承将他们串联起来,更便于修改和维护。可以看出,相较于之前的作业,我在架构设计上的能力有了一定提高,设计中能体现抽象化和层次化的思想,这些也是面向对象编程的精华所在。

    三、测试理解与实践

    (1)第一单元:多项式求导

      第一单元作业的测试要求输入多项式,多项式的随机生成比较简单,根据和python的计算库求得的结果进行比对就可以获得正确性,另外需要根据需求手动生成一些边界数据作为输入。比较麻烦的是错误格式的数据判定,这个部分我基本是靠合法字符的随机组合和直接阅读别人的代码进行互测测试的。

    (2)第二单元:多线程电梯

      多线程的错误由于具有不可复现的特点,而且作业要求延时输入,测试起来比较痛苦。我个人实现的数据生成器只完成了生成一系列随机请求在0时刻输入,评测正确性的逻辑也没有完全实现,只考虑到了请求的完成情况。另外,我发现这种评测机制并不能发现CPU超时的问题,尤其是在多线程中一方没有按时唤醒其他线程导致的CPU超时,这也告诉我在多线程编程尤其要考虑线程安全的问题。

    (3)第三单元:JML规格化设计

      在第三单元中,我接触到了一些其他的测试工具,如使用OpenJML进行规格的正确性检测,以及使用自动化测试工具JMLUnitNG根据规格自动化生成测试数据进行单元测试。但是,这种测试还是有局限性。根据我的实践,它只能根据数据类型生成边界数据,并不能根据我的算法以及需求的实际意义生成数据。

    (4)第四单元:UML图解析

      在第四单元中,由于UML图的特殊性,自动构成测试样例已经不太可能,所以每个测试数据都要使用StarUML来手动构造。我主要构造了一些边界数据,例如多继承带环的接口,以及带环的状态图等等。

    四、课程收获

      本学期的OO课程,收获颇丰,也感谢课程组所做的努力,从官方包以及指导书中都可以看出下了很大功夫,课程体验也比传闻中的好很多。个人收获主要有以下几点:

      面向对象设计架构思想:这也是本门课程的核心所在。在本学期中我通过四个单元的作业,初步理解了面向对象的架构思想,将需求抽象化,利用Java的继承和接口实现层次化地进行架构设计,实现数据和操作的分离。我也学到了很多工程中常用的设计模式。另外,每个单元的增量式作业也要求我们考虑模块的可扩展性。经过课程的学习,大大锻炼了我的架构能力,我的脑中已经有了面向对象架构和编程的整体印象。

      测试能力:本门课程中测-强测-互测的模式也很大程度锻炼了我的测试能力。因为中测数据很弱,很多大数据或者是边界数据都没有被考虑到,而且又有互测需要我们构造数据去Hack别人,都需要我们自己构造复杂的数据。我在前两个单元都自己写了数据生成器和简单的评测机,虽然生成机制都是带有限制的完全随机生成,但也测出了自己和别人的一些Bug。另外,在第三单元,我也接触到了JML的一些测试工具如TestNG等。经过课程的锻炼,我明白了测试对于程序正确性的重要性。

      代码能力和工程能力:课程作业的代码量还是比较可观的,尤其是每个单元的最后一次的作业的代码量和复杂程度都很高,在实践的过程中我的代码水平和工程能力都有了长足的提高。另外,我认为课程组要求的代码风格检查对我们未来工作中写出好维护的代码也有着积极的意义,能够帮助我们养成良好的代码编写习惯。

    五、改进建议

    • 作业需求部分:希望每一次作业的指导书部分能够说明清楚需求以及一些边界条件,排除产生歧义的可能,不要像本学期第四单元作业一样出现到最后再说明数据限制的情况。
    • 测试部分:希望助教能在每单元作业后讲一下这个单元强测测试用例的生成和评测机的判断正确机制,因为测试是OO中很重要的一环,这样可以帮助同学提高自己的测试能力和技巧,也对互测刀人有好处(x)。
    • 上机时间的安排:希望能修改下上机课的时间,最好不要再出现本学期这种上午讲完下午就要上机实践的情况。
  • 相关阅读:
    AliSQL的编译使用
    linux下编译gcc6.2.0
    TransmitFile函数的简单使用
    C++11的简单线程池代码阅读
    TJpgDec使用说明
    TJpgDec—轻量级JPEG解码器
    PPM图片格式及其C读写代码
    linux下vmware的安装、物理分区使用及卸载
    visual stuido 跨解决方案调试
    Proj.4坐标系统创建参数
  • 原文地址:https://www.cnblogs.com/xjc1124/p/11058120.html
Copyright © 2011-2022 走看看