2022-OO-Unit4

2022-OO-Unit4

mashiroly

1. 第四单元架构设计

1. 概述

本单元的需求是实现一个UML语言分析器,支持对类图、顺序图、状态图的查询和部分有效性检查。

2. 迭代

  • hw13

    • MyUmlModel类使用单例模式创建,全局静态共享,用于:管理所有UMLElement,提供查询方法;调用各UmlElement中的方法,构建UML模型。

    • 各类UmlElement的层次关系复刻官方包。提取出同构的抽象结构而不犯错还是挺困难的。

      还需要自行实现方法的UmlElement单独建类,将官方包提供的类与自己实现的类关联。

      Class MyUmlClass {
      	private UmlClass umlclass;
      }
      

      本次作业自行建类的有:MyUmlClass,MyUmlIntetface,MyUmlOperation.

      出于灵活性和可拓展性的考虑,没有使用继承关系。

    • MyUmlModel构建UML模型:多次遍历,按类处理。

    • 指令的实现:(1)MyImplementation调用指令方法get*(),将任务交给指定元素(元素集合),同时完成NotFound,Duplicate异常的抛出;(2)各元素调用具体实现方法,结果返回get*();(3)拼接、整理后返回最上层(Apprunner).

  • hw14

    • 新增顺序图和状态图,其他差别不大。

    • 本次作业自行建类的新增:MyInteraction,MyLifeLine,MyRegion,MyState,MyStateMachine,MyTransition

    • 注意UmlAttribute可能在顺序图和类图中出现,构建时需要根据其parentId区分。

    • UmlPseudostate,UmlFinalState,UmlState统一构造成MyState,检查关键状态时可以方便地递归。

      public class MyState {
         private UmlElement umlState;	//需要时可通过instanceof区分。 
      }
      
  • hw15

    • 本次作业重在阅读理解(。
    • 和指令类似,MyImplementation调用检测方法check*(),将任务交给指定元素(元素集合),将返回值整合为错误信息,其中架构设计上的重点是把具体的检测任务交给哪一层UmlElement。需要整合多个同级元素错误信息的,如R003、R004,单例模式就非常好用。

2. 架构设计思维及OO方法理解演进

还记得第一次作业时,针对表达式化简的需求,我和小伙伴们探讨思路,第一版思路是一个极其复杂的二叉抽象语法树(雾。当我大谈特谈如何传参递归时,小伙伴无意间的一句评价,“好C啊”,宛如当头棒喝。设计合适的架构不应只看到过程上的细节,困扰设计的从来不是代码如何写。这句评价时时警醒我,面向对象重要的是从规则和实例中抽象出对象,建模对象间的协作。

第一单元的主题是层次化设计。

​ 本单元的需求是表达式的解析和化简。一方面,表达式、项、因子根据形式化表述,形成递归的层次化结构。采用递归下降算法,将一个表达式划分为不同层次,各层次的处理由本层的各个对象负责,通过递归调用和返回完成层次内部对象、不同层次间对象的协作。我将其称为“化形式化表述为结构化数据”。

​ 另一方面,因子的种类多样,处理方式各异,但返回时总需要能被项一层处理,项一层的数据也总需要能被表达式一层处理。站在程序员的角度,既然不论何种“算式”都共用同一套计算规则,我们就应该建立一套完备的统一表示,让各级对象的数据可以交互,这催生了对象的”归一化管理“。我的实现是建立Basic类(完备表示数据)和关联Basic类的Factor接口(表示结构),采用工厂模式,让对象能在层次间协作。我将其称为”化程序员所见为程序之所见“。

第二单元的主题是多线程设计。

​ 本单元的需求是模拟多部电梯的调度,重在设计出多线程安全并发协作的架构。采用“生产者-消费者”模式,固定“生产者”和“消费者”,面对不同功能构造不同“盘子”。电梯的运行策略经历了ALS策略到LOOK策略的迭代。在此基础上,通过对线程安全的精心设计,弱化调度、强调自由竞争,以面对非真实场景(指数据或随机或针对性构造,无特征可言)提高性能。

​ 其中第三次作业作为本章集大成者,对于流水线任务划分”流水级“,建立状态机归一化处理。采用worker-thread模式控制流水线任务的传递。并采用类似信号量的机制确保电梯能自由竞争(不重复接人)和正常结束。

​ 在本章中,架构设计确实是难点中的难点。我在设计模式和多线程设计模式中获得不少启发,如单例模式、观察者模式、读者-写者模式等(虽然并没有都用上)。如果以一句话总结,我认为”对共享对象的管理“对理解这些模式最为切中肯綮。

第三单元的主题是规格化设计。

​ 本单元需求是在JML规格的约束下,实现一个模拟社交关系系统。架构设计基本由JML给出,实现上因人而异,体现了”设计和实践的分离“:例如数组改用Map,O(n)/O(n^2)的查询在实现上优化为O(1)等。此外,我在本章进一步强化封装和解耦,将算法打包成工具类,与功能分离。在本单元中我明白了规格描述设计的思想,以及异常处理的方法,顺便复习数据结构(。

第四单元的主题是模型化设计。

​ 本单元的需求是实现一个UML语言分析器(我建模了我的建模语言。

3. 测试理解与实践演进

​ 第一单元主要还是手工构造数据、sympy做正确性检查。由于优化做得较少,并没有太多边界数据(尤其是三角函数)。

​ 第二单元手工构造边界数据能覆盖的范围有限,如针对不同调度策略卡时间、针对不同换乘策略卡结束/卡开门逻辑。主要依靠随机数据生成,采用面向对象的思维搭数据生成器。在小伙伴的正确性检查脚本帮助下覆盖大部分功能测试。

​ 第三单元第一次作业尝试使用Junit单元测试,但渐渐发现测试方法和实现方法越来越像,后续放弃了。本单元搭的数据生成器既能随机黑盒测试,又能针对性构造链、完全图卡qlc,qgav等指令的性能。正确性检查依靠和小伙伴们对拍。

4. 课程收获

​ 在学习OO课程之前,写代码最困扰我的往往是”写“:下一步我应该做什么?这一行代码是在干什么,我改了会有什么效果?但现在我认识到,不论是阅读项目还是搭建项目,理解对象关系、明白架构都是最基础的事。OO课程中学会将事物抽象认识,不仅在代码能力上,也在其他课程(OS理论和实验)上给予我不小的启发。

​ 四个单元的演进、单元内部的迭代让我能初步掌握工程化代码的写法,既能整理好自己的思路,又方便与同学交流沟通。

​ 另一方面,课下作业尤其是测试环节,增强了我和小伙伴们的合作交流,在互相学习中收获良多。

​ 说起来,第一单元第一次作业,觉得自己要进补给站了。没想到一学期下来在磨练中顺利通关,令人感叹。

5. 改进建议

  1. 第一单元第一次、第二次作业好难。从Pre到第一二次作业跨度有点大,建议在Pre阶段给出更多精简的、有效的资料(第一个月翻无数次菜鸟教程警告。一学期下来我觉得JML放在第一单元是一个很好的选择,这章的面向对象很纯粹,不像第一单元杂糅太多复杂的处理(各种因子。当然我理解课程组多年的实践经验一定有更好的理由,这条只是个人想法。
  2. 课上实验无反馈、无答案,可能效果没有Training好(逃。希望未来同学们在课上实验的收获占比,能够与实验占分相比。
  3. 研讨课上,希望老师和助教能更多走下台引导同学们进行讨论,有时候话题和思路打不开正是缺乏老师和助教们的启发。
posted @ 2022-06-29 15:57  mashiroly  阅读(59)  评论(0编辑  收藏  举报