OO第四单元总结
总结本单元作业的架构设计
本单元在架构上的核心思想就是通过对题目中给出的各种element建立自己的element`s adaptor类,使得自己的类能够比题目中包含更多的信息和方法,满足我程序的需求。例如对于每个类的包装类classAdaptor,内部需要额外存储这个类的方法、属性等信息,并且支持对类的查询操作。
下面类图展示了包装类之间的关系和部分额外的属性
classDiagram
class UmlGeneralInteraction
class MyUmlGeneralInteraction{
-MyCollaborationInteraction myCollaborationInteraction
-MyClassModelInteraction myClassModelInteraction
-MyStateChartInteraction myStateChartInteraction
}
class MyClassOrInterface{
<<abstract>>
}
class UmlCollaborationInteraction{
<<abstract>>
}
class MyCollaborationInteraction{
-HashMap<string, umlinteractionadaptor=""> interactionAdaptorHashMap
—HashMap<string, umlinteractionadaptor=""> nameToInteraction
-HashSet<string> duplicatedInteractionName
-LinkedList<umllifelineadaptor> lifelineAdaptors
-LinkedList<umlmessage> messages
-HashMap<string, umlcollaboration=""> collaborationHashMap
}
class UmlStateChartInteraction{
<<abstract>>
}
class MyStateChartInteraction{
-HashMap<string, umlstateadaptor=""> stateAdaptorHashMap
-HashMap<string, umltransitionadaptor=""> transitions
-ArrayList<umlevent> events
-HashMap<string, umlopaquebehavior=""> opaqueBehaviorHashMap
-HashMap<string, umlstatemachineadaptor=""> machineAdaptorHashMap
-HashMap<string, string=""> nameToMachineId
-HashSet<string> duplicateMachineName
-LinkedList<umlregion> regions
-UmlPseudostate pseudoState;
}
class UmlClassModelInteraction{
<<abstract>>
}
class MyClassModelInteraction{
-HashMap<string, umlclassadaptor=""> umlClassAdaptorHashMap
-HashMap<string, umloperationadaptor=""> umlOperationAdaptorHashMap
-HashMap<string, umlparameter=""> umlParameterHashMap
-HashMap<string, umlattribute=""> umlAttributeHashMap
-ArrayList<umlgeneralization> umlGeneralizations
-HashMap<string, umlinterfaceadaptor=""> umlInterfaceAdaptorHashMap
-ArrayList<umlinterfacerealization> umlInterfaceRealizations
-ArrayList<umlassociation> umlAssociations
-HashMap<string, umlassociationend=""> umlAssociationEndHashMap
-boolean emptyName
}
class UmlClassAdaptor
class UmlInteractionAdaptor
class UmlInterfaceAdaptor
class UmlLifelineAdaptor
class UmlOperationAdaptor
class UmlStateAdaptor
class UmlStateMachineAdaptor
class UmlTransitionAdaptor
UmlCollaborationInteraction <|-- UmlGeneralInteraction
UmlStateChartInteraction <|-- UmlGeneralInteraction
UmlClassModelInteraction <|--UmlGeneralInteraction
UmlGeneralInteraction <|.. MyUmlGeneralInteraction
UmlCollaborationInteraction <|.. MyCollaborationInteraction
UmlStateChartInteraction <|.. MyStateChartInteraction
UmlClassModelInteraction <|.. MyClassModelInteraction
MyUmlGeneralInteraction *-- MyCollaborationInteraction
MyUmlGeneralInteraction *-- MyStateChartInteraction
MyUmlGeneralInteraction *-- MyClassModelInteraction
MyClassOrInterface <|.. UmlClassAdaptor
MyClassOrInterface <|.. UmlInterfaceAdaptor
MyClassModelInteraction <-- MyClassOrInterface
MyClassModelInteraction <-- UmlOperationAdaptor
MyStateChartInteraction <-- UmlStateMachineAdaptor
UmlStateMachineAdaptor <-- UmlStateAdaptor
MyCollaborationInteraction <-- UmlLifelineAdaptor
UmlLifelineAdaptor <|-- UmlTransitionAdaptor
UmlLifelineAdaptor <|-- UmlInteractionAdaptor
对于题目中保证两个元素一一对应的地方,比如region,那么我采取了一种投机取巧的方式:在包装类中直接把两个元素进行合并,拥有两个Id
特别的,本次作业中大部分查询都时间没有要求,基本上只要是多项式时间复杂度就一定可以运行完。因此对于判断循环继承的问题上,最开始试图使用一些高级算法,但卡了我很久,最后决定还是每个点挨个遍历,看看是不是属于某个环,时间复杂度O($$n^2$$)
总结自己在四个单元中架构设计及OO方法理解的演进
第一个单元刚刚接触面向对象,写的程序功能性摆在第一位。虽然有结构的设计,但基本上都是按照多项式的元素类型和递归调用的方便,把数据的存储和计算方法分散,形成的结构层次,缺乏总体的思考。这就带来了代码混乱的问题。例如当我为了优化性能,增加了大量的代码。但这些代码就将放到那一层次的类里面,基本上就是随便放的。带来的问题就是代码的可读性不好,类和类之间的耦合度很高,既难以扩展,也非常容易出现各种bug。下面不得不放出当时的Uml图,看了之后心生愧疚,这什么玩意??
![]()
第二单元虽然也以功能性为主,但开始引入各种设计模式。比如生产者消费者模式、电梯的状态模式。虽然代码到处乱放、类间耦合段高的问题依然存在,但因为代码以几个成熟的设计模式为模板展开书写,总体上还是层次性相对较好的。
![]()
第三单元其实可以讨论的并不多,主要是因为Jml语言对代码的书写限制性太大了,在结构层次上基本没有自己发挥的余地。
第四单元我明显感觉自己的结构设计能力变好了(或许是因为难度比之前简单了)。一方面架构的层次更加立体了。例如class和interface在很多查询操作中具有相同的处理方法,于是我建立了MyClassOrInterface类,class与interface的包装类分别继承他。通过这个小操作,让代码的复用性和耦合度大大降低。此外,为了实现高内聚低耦合的目标,我在本单元的作业中努力界定好各个类之间的功能差异。有的类就是用来进行数据存储的,对外只提供少量的直接的get方法。但对于复杂的查询操作,就由专门的类实施。
这也让我觉得,高内聚低耦合的重要前提就是要区分清楚类之间的功能,先对功能进行层次划分,再对类进行设计。
总结自己在四个单元中测试理解与实践的演进
第一单元作业:评测机是最好写的。数据直接使用正则表达式生成,结果通过python直接比较。也是我正确性唯一满分的一个单元
第二单元作业:基本无法测试,评测机过于复杂。由衷敬佩身边依旧在写评测机的大佬们。针对多线程问题,评测机这件事,还是超出了我的能力。只能依赖于简单的样例的人眼检查。
第三单元作业:编写评测机,对拍。
第四单元作业:临近期末无时间测试。
个人对评测机的一些理解或感想如下:
- 对于有确定解的问题,好办。需要对拍的,也没问题。多线程啊,太难了!
- 自动生成数据虽然听起来美好,但对边界情况的覆盖程度很差。关键的边界数据还需要手动构造。
- 评测机的结构其实不难,就是调用进程,获得进程运行时间和结果再比对。难点永远是数据!
总结自己的课程收获
- 学会了java!代码功底更好了。
- 初步掌握了多线程的编程思想,学会了几种设计模式
- 面对一个问题,能够更加从容地入手了,明白了对于一个较为一般的编程任务的编写步骤,对代码的设计能力更好了
- 初步了解了迭代式开发
- 学会了编写简单的评测机
- debug能力变强了
立足于自己的体会给课程提三个具体改进建议
- 上课实验建议提供答案,oo网站上有关上课实验的内容也建议不要一下课就关闭
- 为什么代码风格忘记改了会造成如此严重的扣分并且不允许修改?建议课程组考虑一下这个政策的合理性。
- 是否可以是否可以适当减少三四单元的内容,增加一次供学生自主发挥余地更大的大作业?
- 第四单元的指导书啊,实在是写得,有待提高。
- 上课感觉大家的积极性实在不高,是否可以引入小组讨论的形式?