U4 Summary

BUAA_OO U4 Summary

1.单元架构设计

| - MyImplementation          
	| - MyClass
    	|- UmlAttribute
        |- MyInterface
		|- Myoperation
			|- UmlParameter

​ 在本单元的作业中, 我并没有使用UmlClass、UmlOperation、 UmlInterface等官方包自带类,而使用自己实现的Myclasss类。一是因为对于上述类所需要关注的原始属性只有Id,ParentId,Name,官方包中上述类的结构较为复杂(其实是我看不懂),更重要的是,可以根据指令要求灵活地在各层结构中设置属性、方法,抛出异常。但是,对于不需要额外方法、内部属性的UmlParameter、 UmlAttribute类,并不需要实现自己的类,使用官方包自带即可。

​ 在层次化建模下,我们对于指令的处理结构也遵循层次化的原则,例如查询类方法的耦合度时,在Myclass类设置可以访问是否为重复操作或存在错误类型的方法,该方法的实现为调用Myope类中判断是否为重复操作和存在错误类型的方法,在impletation设置对于上述异常的抛出异常处理;对于符合要求的正确情况,在Myclass、Myoperation设置得到耦合度的方法,其中在Myclass类中实现为计算Myoperation的耦合度返回值总和。

| - MyImplementation
	|- MyDiagram
    	| - MyClass
    		|- UmlAttribute
        	|- MyInterface
			|- Myoperation
				|- UmlParameter
				
	|- MySequenceParse
		|- MyInteraction
			|- MyLifeLine
			|- UmlEndpoint			
			
	|- MyStateMachineParser
    	|- MyStateMachine
    		| - MyState
    			| - MyTransiition
    				| - UmlEvent

​ 值得说明的是,上述结构并不是正确的层次简的逻辑结构,而是在我的层次实现中的实现关系,比如MyTransition在设计中为MyState类中的属性,state对象可以调用transition类的方法。

​ 在第二次作业中,为了实现层次的清晰,我将对类图、时序图、状态图的解析分别建模。此外,值得说明的是,我在此次作业作业采用了分层次异常抛出

​ 例如在时序图中返回对象创建者的查询指令实现中,我在MySequenceParse的层次中抛出 InteractionDuplicatedException()InteractionNotFoundException();随后调用MyInteraction类方法,在此层次中,抛出 LifelineDuplicatedException()LifelineNotFoundException()异常,最后在MyLifeLine类中抛出 LifelineNeverCreatedException()LifelineCreatedRepeatedlyException();

public UmlLifeline getParticipantCreator(String s, String s1) throws
            InteractionNotFoundException, InteractionDuplicatedException,
            LifelineNotFoundException, LifelineDuplicatedException,
            LifelineNeverCreatedException, LifelineCreatedRepeatedlyException {
        if (interactionWithNames.containsKey(s)) {
            return interactionWithNames.get(s).getCreator(s1,umlLifeLines);
        } else if (dupInteraction.containsKey(s)) {
            throw new InteractionDuplicatedException(s);
        } else {
            throw new InteractionNotFoundException(s);
        }
    }
    
 MyInteraction :
 
    if (lifeLineWithNames.containsKey(lifeLineName)) {
            return lifeLineWithNames.get(lifeLineName).lifeLineGetCreator(this.getName(),lines);
        } else if (dupLifeLine.containsKey(lifeLineName)) {
            throw new LifelineDuplicatedException(this.getName(),lifeLineName);
        } else {
            throw new LifelineNotFoundException(this.getName(),lifeLineName);
        }
        
MyLifeLine:
	if (creators.isEmpty()) {
            throw new LifelineNeverCreatedException(interNa,this.getName());
        } else if (creators.size() > 1) {
            throw new LifelineCreatedRepeatedlyException(interNa,this.getName());
        } else {
            return lines.get(creators.get(0));
        }

​ 其实,上述架构的原因很明显,由于我们采用层次化设计的方法,所以每个层次的类就管理一定层次下的数据,以当前层次不能判断是否需要抛出异常,所以我们就将抛出异常的决定权交由下一层次。

架构设计总结

  • 面对着第一单元第一作业,回忆起架构设计的过程可谓非常艰难;尽管有着pre2的预习经验,但入手表达式的建模仍不是一件一件的事。首先需要构建起解析字符串的模式,在这个过程中我也学会了递归下降,学会了由构建Parser类、Lexer类等某一特定类型的类来实现我们的解析过程,这也呼应了我们在计组中学习到的“高内聚,低耦合”的思想吧;随后,更为重要的是,我们需要建模来表征运算因子、运算符,在第一次的作业中,我竟然有过由字符串表示因子的想法,我们初步开始应用面向对象的思想,什么是对象,在这作业中,运算因子就是对象,我们需要建立运算因子专属的类来表征他们,并通过一定的容器管理这些因子对象。当建立运算因子的类后,就需要将运算符抽象为每个类的方法。

  • 第二单元的训练过程中,在初步面对多线程的束手无策到看到实验代码后的豁然开朗,可谓是“守得云开见月明”。第二单元的架构,更像是一个流水线,各个工种在同一时间各司其职。在设计架构时,引入输入处理类、调度器类、电梯类、候乘表类;输入处理线程、调度器线程、电梯线程同时工作。其中,候乘表作为共享对象,需要封装成线程安全的类,以实现各个线程的互斥访问、存取。

  • 第三单元的主题是规格,规格中的抽象数据、抽象方法其实已经包含了对于层次架构的设计,在这一单元,我的架构设计以实现整体规格为主,并辅助设计几个特殊的类来实现并查集判断是否为公共父节点、构建用于规划最短路径、最小生成树的小堆顶。

  • 第四单元的整体架构其实由类图、时序图、状态图的结构决定,在这个单元的作业中,我更能体会到一种层次化设计的鲜明特点,所有的指令实现由实现UML图的各个层次的类分层次部分实现。

    ​ 对oo思想的演进:

    ​ 一开始对于oo的理解是,对一些具有鲜明结构的数据,或者是对一组具有联系的数据,用一个特定的结构来存储并设置一系列方法来管理。确实也算是入门级的理解了(笑哭。

    ​ 到一单元,在我自己开始独立设计复杂的方法实现时,深刻地体会了oo思想带来的便捷。在表达式类中构建乘法方法时,突然想到,表达式由因子组成,如果以常规方式实现,这个乘法方法太过于复杂;但其实,在表达式类的乘法只需要关注实现逻辑,及有限个,表达式A中的因子A1和表达式中因子B1的乘积之和。所以,当我捋清这一关系后,只需要实现因子类的乘法即可,而因子类的乘法实现也已经实现。所以,在我的理解中,oo建模思想是有助于代码复用,和简化设计

    ​ 后续,又看见实验代码中Parser类和Lexer类的解析表达式器设计,感觉oo思想又莫名眼熟,这不我们CO时期模块化的低耦合和高内聚

    ​ 在完成第四单元时,我也再一次体会了,当我在重构某一个指令实现时,途中只出现了一个类的飘红,我想其中原因,无非是做完了层次化设计后,我们各个层次、各个类的实现都只是对自身的管理,不会牵一发动全身,相较于面向过程的编码,一处修改,往往可能带来处处填坑。

    ​ 总结而言,其实OO思想更为重要的时候,分层次建模,归纳层次架构时,我们完成了对有联系的抽象数据的梳理、抽象方法的构造,这样才有助于各个不同的类各司其事,不因为某个类变化影响其他类。

课程收获总结

​ 1.在第一单元中,在额外学习递归下降解析的基础上,以Expression表达式、Factor因子分层次对运算因子和运算数完成了建模,第一次以面向对象的方式思考分析形式化语言的实现,也学会BNF形式化表达。

  1. 在第二单元中,第一次了解了多线程,学会多线程互斥访问共享资源的写法。

  2. 在第三单元,开始接触契约式编程,其实感觉更像是面向规格编程。

  3. 第四单元,进一步深化了层次化设计架构思想。

测试

​ 在第一单元前期,主要使用sympy库生成正确答案进行对比,但到第二次、第三次作业就需要和同学进行对拍。

​ 在第二单元,没有自主完成测试。第三、四单元主要采用随机生成数据+ Subprocess库构建子进程+与同学对拍完成。

对课程的建议

1.建议在pre环节训练表达式建模的思想,降低第一单元的引入难度。可以先由后缀表达式解析训练来完成实现运算符、运算因子的建模。

2.引入现场答疑环节,对每单元的建模架构可进行指导。

3.完善研讨课制制度,建议固定分组,每次研讨课轮流划分记录、发言分工;在讨论内容相对较少的第三、第四单元可以引入小组自由决定讨论内容的策略。

posted @ 2022-06-29 13:08  j[k]{2}  阅读(37)  评论(0编辑  收藏  举报