第四单元总结性博客作业

一、架构设计

1、第一次作业

本次作业中, 实现了对类图的分析功能, 主要考察对UML类图的理解和官方包内代码的阅读中, 只需要在一个MyImpletation类中维护多个数据结构的方式来进行存储,

    private UmlElement[] elements;
   private int classcount = 0;
   //父类name->子类name容器
   private HashMap<String, ArrayList<String>> fatheridextendsonid = new HashMap<>();
   private HashMap<String, String> id2classname = new HashMap<>();
   private HashMap<String, String> id2operationname = new HashMap<>();
   private HashMap<String, MyNode> id2operationnameid = new HashMap<>();
   private HashMap<String, MyNode> id2attributenameid = new HashMap<>();
   //统计类名重复
   private HashMap<String, ArrayList<String>> classname2id = new HashMap<>();
   //统计类name->操作name
   private HashMap<String, ArrayList<String>> classname2operationname = new HashMap<>();
   //统计操作名重复
   private HashMap<String, ArrayList<String>> operationname2id = new HashMap<>();
   //统计操作id,name->UmlOperation
   private HashMap<MyNode, UmlOperation> name2visibility = new HashMap<>();
   //统计类name->操作id,name的容器
   private HashMap<String, ArrayList<MyNode>> classname2operationnameid = new HashMap<>();
   //统计操作id,name->类name
   private HashMap<MyNode, String> operationidname2classname = new HashMap<>();
   //统计操作id,name->参数Umlparameter传入的容器
   private HashMap<String, ArrayList<UmlParameter>> operationid2UmlParain = new HashMap<>();
   //统计操作id,name->参数Umlparameter返回值的容器
   private HashMap<String, ArrayList<UmlParameter>> operationid2UmlParareturn = new HashMap<>();
   //统计操作id,name->参数type列表
   private HashMap<MyNode, HashMap<String, Integer>> operationidname2reftype = new HashMap<>();
   //统计属性id,name->UmlAttribute
   private HashMap<MyNode, UmlAttribute> attributeidname2uml = new HashMap<>();
   //统计类id->ref属性id,name的容器
   private HashMap<String, HashMap<String, Integer>> classid2refattributeidname = new HashMap<>();
   //统计类id->接口id的容器
   private HashMap<String, ArrayList<String>> classid2interfaceid = new HashMap<>();
   //统计接口id->name
   private HashMap<String, String> interfaceid2interfacename = new HashMap<>();
   //统计接口name->id
   private HashMap<String, String> interfacename2interfaceid = new HashMap<>();
   //统计子类->父类
   private HashMap<String, ArrayList<String>> sonid2fatherid = new HashMap<>();
   
   private HashMap<String, Integer> anshashmap = new HashMap<>();

本次作业我主要通过hashmap数据结构进行存储,便于查找,大大降低时间复杂度。

2、第二次作业

本次作业增加了对状态图和顺序图的解析,于是我添加新添加的两个类MyCollaboration和MyStateMachine来分别实现顺序图和状态图的解析,保证了每个类不会超过500行。

本次作业增加的内容并不算多 ,关键路径解析中我使用的是深度优先算法, 其他的新增查询功能相对而言都比较简单。

MyStateMachine类

    //Interactionid->name
   private HashMap<String, String> intid2intname = new HashMap<>();
   //Interactionname->id容器
   private HashMap<String, ArrayList<String>> intname2intid = new HashMap<>();
   //Interactionid->lifeid容器
   private HashMap<String, ArrayList<String>> intid2lifeid = new HashMap<>();
   //Interactionid->lifeUML容器
   private HashMap<String, ArrayList<UmlLifeline>> intid2lifeUml = new HashMap<>();
   //lifeUML->startmessageUML容器
   private HashMap<UmlLifeline, ArrayList<UmlMessage>> lifeuml2messageuml = new HashMap<>();
   //endid->endaname
   private HashMap<String, String> endid2endname = new HashMap<>();
   //lifeUML->foundendid容器
   private HashMap<UmlLifeline, ArrayList<String>> lifeuml2endidfound = new HashMap<>();
   //lifeUML->lostendid容器
   private HashMap<UmlLifeline, ArrayList<String>> lifeuml2endidlost = new HashMap<>();

MyCollaboration类

    //状态机id->name
   private HashMap<String, String> smid2smname = new HashMap<>();
   //状态机name->id容器
   private HashMap<String, ArrayList<String>> smname2smid = new HashMap<>();
   //状态机id->画布id
   private HashMap<String, String> smid2regionid = new HashMap<>();
   //画布id->状态Uml容器
   private HashMap<String, ArrayList<UmlElement>> regionid2stateUml = new HashMap<>();
   //状态机id->状态Uml容器
   private HashMap<String, ArrayList<UmlElement>> smid2stateUml = new HashMap<>();
   //状态机id->(father容器,状态uml)容器
   private HashMap<String, ArrayList<MyUnion>> smid2fatheraddstateUml = new HashMap<>();
   //状态id->状态机id
   private HashMap<String, String> stateid2smid = new HashMap<>();
   //画布id->状态机id
   private HashMap<String, String> regionid2smid = new HashMap<>();
   //转换id->转换name
   private HashMap<String, String> transid2transname = new HashMap<>();
   //转换UML->事件id容器
   private HashMap<UmlTransition, ArrayList<String>> transuml2eventidlist = new HashMap<>();
   //事件id->事件name
   private HashMap<String, String> eventid2eventname = new HashMap<>();

 

3、第三次作业

在本次作业中,加入了对UML图异常的检测机制,总体实现相对而言也并不复杂, 为了不影响之前两次作业的逻辑结构,对本次作业的异常检测单独开了一个MyCheck类

MyCheck类

    private HashMap<String, String> id2name = new HashMap<>();
   
   private HashMap<String, String> classid2classname = new HashMap<>();
   
   private HashMap<String, ArrayList<UmlElement>> classid2attrarray = new HashMap<>();
   
   private HashMap<String, UmlAssociationEnd> assoendid2asso = new HashMap<>();
   
   private HashMap<String, ArrayList<String>> sonid2fatherid = new HashMap<>();
   
   private HashMap<String, UmlElement> id2umlelement = new HashMap<>();
   
   private boolean isduplicatedgeneralize = false;
   
   private boolean isincircle = false;
   
   private HashMap<String, ArrayList<UmlElement>> interfaceid2attrarray = new HashMap<>();
   
   private HashMap<String, String> intid2collabor = new HashMap<>();
   
   private HashMap<UmlLifeline, UmlAttribute> umllife2umlattr = new HashMap<>();
   
   private HashMap<String, UmlAttribute> attrid2attr = new HashMap<>();
   //收到消息
   private HashMap<String, ArrayList<UmlMessage>> lifeid2umlmessage = new HashMap<>();
   //finalstate迁出
   private HashMap<String, ArrayList<UmlTransition>> finalstate2transitionsource = new HashMap<>();
   //所有状态除finalstate外的迁出
   private HashMap<String, ArrayList<UmlTransition>> stateid2transitionsource = new HashMap<>();
   //事件parentid2事件uml
   private HashMap<String, ArrayList<UmlEvent>> eventparentid2umlevent = new HashMap<>();

 

4、架构设计

1656412622863

在本单元的作业中,构建的代码结构非常简单,只要严格遵守指导书要求,是没有问题的,HashMap数据结构简单明了能带来更加直观的理解,大大降低产生bug的几率。

二、课程总结

四个单元中架构设计思维及OO方法的理解

层次化设计是架构设计的核心

第一单元 表达式展开

通过对表达式结构进行建模,完成多层嵌套表达式和函数调用的括号展开与化简,在这个单元的学习中,我学习了如何通过数据层次以及行为层次进行设计,并以面向对象的方式思考问题,熟悉了正则表达式处理字符串的手段,了解了对于代码的不断更新迭代满足需求。

 

第二单元 电梯多线程

多线程是java语言的核心之一,本单元模拟多线程实时电梯系统,熟悉线程的创建、运行等基本操作,熟悉多线程的设计方法。第二单元主要对线程这一对象进行一系列操作,由于线程的并发性,我主要采用生产者——消费者这一设计模式实现不同线程之间的互斥访问。使用同步块方法,设立共享对象并使用同步(synchronized保护不同线程对其的并发访问,完成了多个并发运行的线程进行数据交互或共用工具的业务需要。在不同线程交互的时候,需要使线程在无法获取资源时进入等待状态,释放cpu资源 。在第六次作业我使用ReentrantReadWriteLock读写锁,放弃使用了sychronized关键字,唯一使用sychronized的类是线程安全输出类SecuredTimableOutput

 

第三单元 JML规格

规格是开发人员需要实现的要求。 对于JML语言,它以一种数学语言的方式,明确了所需求的规格,消除了自然语言的歧义性。在规格层面上,不需关心具体实现方法,但要求程序运行产生的所有效果都在约束之内。 选择合适的容器并按照JML规格进行搭建基本上就不会出现什么bug 。

 

第四单元 UML解析器

UML语言是一个支持模型化和软件系统开发的图形化语言,为软件开发的所有阶段提供模型化和可视化支持,包括由需求分析到规格,到构造和配置。建立好层次化结构后需要根据根据相应的条件(指令)进行搜索和访问,因此在建模过程中就需要选取适合的图模型来封装类图、顺序图和状态图模型。

 

四个单元中测试理解与实践的演进

第一单元 表达式展开

基础测试: 测试好简单的基础功能,自己编写一些能想到的bug测试样例,能通过上次的强测数据和本次中测中可显示的测试点。

边界测试:大数和0、-1、1,运行时间的极限测试。

 

第二单元 电梯多线程

自动化测试:和同学组队,借助同学的评测机,用大量的测试样例来保证代码的正确性。

边界测试:在允许投喂时间的最后一秒,投入大量的数据,检验数据运行时间的极限。

 

第三单元 JML规格

代码基本都是按照JML语言的描述编写,因此正确性错误出现的概率很低。

和同学对拍,可以进行正确性检验,检测程序的实现难度大大降低,被同学生生地带飞了。

 

第四单元 UML解析器

测试好简单的基础功能,自己编写一些能想到的bug测试样例,与同学分享bug测试样例。

 

三、课程收获

在OO课程的学习过程中,也逐渐养成了一套系统的OO编程的测试方法。

每一单元各有收获。第一单元初次接触面向对象的建模,对类、接口以及它们之间的层次关系有了初步的理解和认识。第二单元在线程协作方面从零到有了初步的了解,理解了并发协作的便利性和多线程或多进程的重要性。第三单元学习了JML规格,理解了规格满足与具体实现。在清晰的规格下,每个人只需通过接口无需知道实现地调用相应方法进行操作。第四单元学习了UML模型,进一步理解了面向对象的分层机制,同时学习了基本的顺序图和状态图模型。

 

四、改进建议

1、pre的难度与实验课四个单元的难度相差太大了,pre只是简单的类和简单的继承,而实验课涉及许多算法思想和java语言特性如:递归下降和多线程,对于我来说,感觉pre并没有起到铺垫作用。

2、互测的意义发生了变化,大部分人用评测机取轰炸别人的代码,互测又变成了强测,互测的存在并没有起到让同学互相读代码的作用。

3、互测时间太短了,就只是互测一个白天(8点到23点),如果课程组希望的是大家把同组的7、8个人的所有代码都读一遍,这么短的时间未免有些仓促。

 

最后祝北航OO课程越办越好!