BUAAOO 第四单元 & 课程总结

1. 第四单元:StarUml文件解析

本单元采用了图模型解析UML。

UML文件可以抽象为图、子图、边的逻辑结构。

在实现中,图的节点包括类、接口、属性,子图包括状态图、顺序图等。

采用了三次遍历UML元素的方法建图,第一遍遍历建点,第二、三次遍历设置属性、连边,实现图对象的初始化。这里借鉴了一些python程序设计的思路,通过迭代器、选择器快速完成数据处理,实现起来代码编写效率比较高。

类、接口节点继承自可继承节点抽象类,实现了对继承的判断。

总流程为:

umlInteraction交互 - parser建图 - graph节点存储信息 & 定义查询方法 - umlInteraction交互

2. 架构设计总结

第三次第四次架构较为简单,这里主要借助JML规则、UML图的知识,对前两次作业的架构进行回顾。

2.1 对象概念的提取

面向对象的第一步就应当是提取出对象概念,并找出继承、关联关系,进行封装。

在表达式求导作业中,对象概念的提取的原则是规则。对于初等函数,需要实现的求导规则为:

  • 线性法则

  • 乘除法则(莱布尼茨公式)

  • 链式法则

  • 特殊函数求导(幂函数、三角函数、对数函数、指数函数、....)

通过这些法则理论上生成任何初等函数的导数。即在初等函数范围内,求导规则具有完备性。

基于这种思想,结合表达式树模型完成了对象概念的提取。每一个表达式树上的节点作为一个Item对象存在,同时代表一个基础的求导规则体。

对于化简,实现的部分规则为:

  • 节点自我化简
  • 节点之间加减乘化简
  • 三角函数+加减乘化简

考虑到化简规则和求导规则的对应关系不清晰,因此单独建立了化简接口,在表达式树上通过递归访问接口方法实现化简。这种架构的不足之处在于,每一个化简规则被分散在了多种表达式树节点上,不利于维护,而表达式树节点的分类是根据求导规则进行的。

一种改进方法是对节点对象添加运算规则,化简法则通过对运算规则的操作间接完成化简。

另外节点之间化简搜索空间非常大,可能还需要一些随机化方法完成化简,还应添加一些随机化的化简规则。


对于第二单元作业,电梯调度的对象概念提取的原则为状态。借助UML图的知识我们可以看到,并发程序可以由时序图描述,而时序图中每一个对象可以被视为一个状态机。状态机之间通过消息的传递完成并发任务。

因此,应当抽取了需要维护状态的概念作为对象。同时每个对象的状态数目不宜过多,且内部联系紧密,外部联系疏松。这里抽取的三个状态为策略缓存、调度板、电梯状态。

同时,MainClass中的读取线程、Executor线程作为消息的发出者,负责保持对象间的协作运行。

graph LR MainClass--Requests-->Schedule MainClass--Create-->Elevators Schedule--Check-->Elevators Executor--Operate-->Elevators Executor--Notify-->Schedule Schedule--Update-->Executor Schedule--Adapt-->Method

第三次作业直接实现了提供的接口。社交网络使用的是图论模型,这里使用了点、点集合作为对象。

第四次作业UML文件解析,同样采用的是图模型。而这里使用的是查询的内容的逻辑结构为对象。包括类、接口、属性、状态图、顺序图等。

2.2 对象创建模式

第一单元表达式求导课程中,第一次讨论了对象创建模式的问题。

这一单元主要的程序设计为:

表达式读取 --> 表达式元素对象 --> 调用元素求导方法 --> 调用元素输出方法

不过在一开始表达式读取模块中,使用了状态机模型,但实现的较为复杂,难以维护。在第二次、第三次作业中,参考了工厂设计模式。一个重要的改进就是强化了状态机模型和表达式元素对象之间的耦合关系。对于每一类表达式元素,采取独立的解析器,各个解析器分层解析。每一个解析器类似于一个工厂。

这种方式的优势在于,较好地将需求中的归纳定义表达式元素对象的结构映射在了设计架构中。一个还应当改进的方面是循环依赖问题,可以通过抽象出统一的解析器接口,再对解析器对象进行组装来解决。类似于抽象工厂模式。


在第二单元作业中,采用了这种在再组装的策略。分别为执行器模块、调度器模块、策略模块、电梯模块。各个模块在MainClass完成对接,模块之间的实现细节对其他模块不可见。这样就避免了模块组装时产生的循环依赖问题,可以理解为所有模块都依赖于规则集合,而组装的过程又依赖于全部规则集合、模块实现集合。

抽象工厂模式/再组装的优势在于,采用了“模块化”的生产理念,各个部门在同一的规则下行事,部门与规则之间的联系强于部门之间的联系,避免出现部门之间的循环依赖,或者说互相扯皮、推卸责任、“抛皮球”情况的发生。

先进的社会是法治的。


而在第四次作业中,采用了三次遍历UML元素的方法建图,第一遍遍历建点,第二、三次遍历设置属性、连边,实现图对象的初始化。这里借鉴了一些python程序设计的思路,通过迭代器、选择器快速完成数据处理,实现起来代码编写效率比较高。

其实无论哪种对象构建模式,都应遵循贴近实际、简洁易维护的原则。贴近对象数据结构,问题的逻辑结构,不要刻意迎合某个设计模式。不管黑猫白猫,能捉老鼠的就是好猫。

3. 对面向对象方法的理解

面向对象的方法是对事物刻画的一种方式。

从宏观层面上来看,世界的构造具有同构性。例如,地球绕太阳运动,而月球又绕地球运动。从科学的角度来看,这背后具有相似的物理原理和数学规则,可以通过数学方法进行抽象。

面向对象将这种规则化转化到了程序中,自然而然地诞生了抽象、分层、复用的特性。

科学的一个重要方法是“奥卡姆剃刀原理”。即“如无必要,勿增实体”。面向对象作为规则的描述体,也具有 “封装,继承,多态”的类似特点。“封装”对外部访问的限制,“继承”即对重复规则的限制,“多态”即对接口信息量的限制,同名接口可以处理更多信息。

面向对象也是工程学的协作方法。从工程化的角度而言,标准化是必不可少的部分。标准化意味着对产品、模块的行为有确切的约束,我们只需要知道标准就可以进行协作,而无需知道对方的生产过程。

因此一个高效的程序应满足模块化、高耦合、低内聚的特点。

一个成功的面向对象的系统应是完备、简洁、高效的。

4. 课程收获

  • 思考、实践、总结了面向对象程序设计的方法论
  • 学习了并发程序的设计方法
  • 学习了JML语言和UML建模方法
  • 实践了Python、Junit测试方法
  • 简单实践了一些优化方法

5. 课程建议

  • 希望可以改进教学的顺序,JML、UML两个单元可以先讲,因为这两个单元偏向理论,而另外两个单元偏向应用,且更为综合。
  • 希望JML、UML单元可以布置一些开放性的作业。
  • 希望以后在线课程老师可以出镜,并且将视频按知识点分块。一些MOOC是这样的,感觉效果会明显更好些。
(0)

相关推荐