一,第四单元架构设计
第一次作业:只有类图
1,重置MyClass,MyOperation等类,为使里面只有必要数据(name,id,visibility等)、或方便组织数据(如MyClass作为其底下所有operation、attribute等数据的管理容器)
2,MyUmlInteraction 用来管理所有数据和方法
3,输入处理:由于所有的元素传入的顺序不定,所以可能出现operation的parameter先出现等类似情况,所以所有不同类数据之间的联系都以各自的id值作为代表,而形成的“一棵棵树”,UmlInteraction中另设HashMap管理每个id对应的实际对象
4,在所有数据被传入完之后,将每个class元素进行一次“寻找顶级父类”的操作,并在逐级递归的过程更新每个子类的“顶级父类”、“重复的attribute名字”、“所有attribute的名字”、“所有关联的类\接口的名字”,到时候遇到指令“attribute数量”、“关联的类\接口名字”等时能直接进入到相应class中获取。
5,一点可能不必要的设计:为适应命令“是否违背信息隐藏原则”,将所有非private的attribute元素的名字和其所在的类的名字组合,放入class中的一个ArrayList中,在“寻找顶级父类”时,更新,从而最后能直接输出
主要的实现可以见下图:
* attribute和interface没有重置相应的类,因为attribute只要记录它在哪个class中,名字、id、visibility,所以完全可以以“幽灵”存在,即将其名字、id、visibility按需组合,存入相应的MyUmlInteraction类中或Myclass类中的某个hashmap中就行了,而interface只要记录它的“father”有哪些、在实现了其的相应的Myclass类中记录其id/name就行了
attribute主要存在
interface的“father”以HashMap<String id ,HashSet<String id>>在MyUmlInteraction类中被记录,当然MyUmlInteraction类中会专有HashMap<String id,String name>来记录各个id对应的interface的name,而且在传入所有元素后会将所有interface遍历一遍,使其得到所有的“祖父”、“曾祖父”、“曾曾祖父”……
(1)Myclass类中:
a,对attribute:
自己定义或父类继承来的attributeHashMap<String name,String id>
从association_end得来的attribute的name,boolean chongfule(“重复了”)是用来判断其是否自己定义的attribute中有重复的——这样与上面的repeated_attribute的作用有一点重复,属失误
b,对operation:
下面是专门统计各类“有参数方法”、“有返回值方法”等的数量,而非像上面一样用hashMap专门存储,算一点简化
c,继承自父类的:
所有的父类的id、所有的association的name、所有实现的接口的name:
(2)MyUmlInteraction类中
对class:
对association:
*下面的两个是在传入所有的元素后进行的association和class之间的“连线”,将其按class管理起来
对interface:
同class类似,但没那么仔细(因为涉及的数据种类不多)
对operation的管理
对class和interface的parent_id的管理
第二次作业:
1,数据的管理:
相比第一次,平行增加对时序图、状态图的数据和方法的管理,比对类图的管理要简单一些
一点注意:(1),状态图的元素传入时,对起始状态和终止状态的处理,以及对终止状态的“incoming message”的处理,不过最后没有相关命令,也可不处理
(2),所有元素传入完毕后,将每个状态递归处理,找到其所有的后继状态,存好
对状态图:
对时序图:
2,关于r001/r002/r003三个法则的处理:
(1)r001:在每个class中添加HashMap存储其所有end端的attribute的名字,最后将所有class元素遍历一遍,看是否有重名的
(2)r002:先对class元素遍历“寻找顶级父类”,并用临时的全局hashMap容器存储经过了的class元素id,当当前的“father的id”在容器中出现过时,将当前容器中的所有元素“一锅端”
再对interface元素遍历,深度优先算法,也是“一锅端”
(3)r003:我用了讨论区里的方法,将所有的class元素和interface元素结合看成同一类节点,使用DP算法,遍历所有class元素和interface元素
使用到的容器:
r001:
与association相关的容器联合使用
r002:
r003:
总之这一单元的架构设计主要是:
元素“抽象后存储”,如Myclass类中只存operation的id;
元素“集中管理”,如MyUmlInteraction类中集中存储所有id对应的class/operation/interface等元素的实际的类的数据;
元素的“传入后完善”,如Myclass类中的“所有attribute”会在所有元素传入后、在进行一次“寻找顶级父类”操作中被完全地完善(得到父类的attribute);
方法的“深度优先”,如对r003法则的实现。
*很遗憾,没有将类图、时序图、状态图分开到不同类中进行管理,因在这次作业中这三者几乎无关;另外,由于我处理传入的元素的方法很繁杂,所以应将对数据的处理另放入一个类统一管理,然后MyUmlGeneralInteraction类中应主要应对功能的实现。总之,类中代码超了500行……
一点数据:
*下面红色的getspeopnum是get_specific_operation_number(得到特定类型的operation的数量)的方法
*下面的红色的“checkcf”(check_chongfu(重复))方法是用了递归,是用来检测是否有循环继承的类的方法
*下面的红色的“chulijiekou(处理接口)”方法是使所有接口得到其所有的父类id(包括父类的父类……)
“copygettop”是递归找到所有类的顶级父类,并在过程中更新各个子类的“attribute"、"association_list”等容器中的数据
"getTopParent"与“copygettop”方法几乎相同,不过其是根据class_name 而非 class_id来进行查找的,在执行时实际将是直接得到"top_father",并不会有递归之类的,属失误
*下面红色的“qingli(清理)”方法是在传入所有元素之后,检测r001,r002,r003并同时完整所有数据及其管理的数据的方法(比如使所有class得到了其父、曾祖父、曾…祖父的attribute_name)
*下面红色的“addop”方法是“add_operation”方法,是class加入其所有的operation的方法
二,四个单元中的架构设计
第一单元:主要元素的区分
第二单元:主要元素的区分和分工
第三单元:最合适的容器、方法的选择
第四单元:主要元素的区分、最合适的方法的选择
*CLorin类是“Class or Interface”类,作为对class和interface的抽象后统一的类
三,测试理解与实践的演进
第一单元的理解:判断WF的疏漏、求导过程的不完善
第一单元的测试:看代码+分解其判断WF的“if…else”语句和求导过程的部分,定点轰炸。结果:疏漏很多,而且自己没有能力能判断出其处理有bug
第二单元的理解:看代码+无脑测试
第三、第四单元:按照自己思考时出的错误定点轰炸,结果:收获良好(因为自己也很菜)
四,课程收获
1,能更好地划分各种元素:如第一单元中对“常数”、“三角函数”、“带x的乘数”的区分,第二单元中对“电梯”、“中央管理器”、“需求输入器”的区分,第四单元中对类图中各类元素、时序图中各类元素、状态图中各类元素的区分
2,能更好地明确和区分各种元素之间的关系:如第一单元中对“项”之间的关系的区,第二单元中“电梯”和“中央管理器”的关系和各自的分工、第四单元中类图的“class”和“attribute”的关系
3,模块化的自我测试:在将功能进行划分后,按模块进行编写代码,写完一块测一块
4,更能注意程序的易错点
五,三个建议
1,实验课可以简单一点?虽然写完代码后回顾感觉当时题目的确是比较基础,但在当时做的时候有几次会感觉信息量有点多,另外可以循序渐进地专门训练我们的归纳分析元素的能力?这样在那道出租车题前就不会有些手忙脚乱了
2,bug修复界面在“预览”时能不算“提交”?不过这样评测机的压力会很重……所以能否降低“预览”而未“提交”情况的等待时间?
3,bug修复在情况:有2个bug,但在十几个测试集中,都同时包含了涉及这两个bug的命令,若只修复一个则还会只是“无效修复”,只能当做几十个bug一起修复……也许考虑了这种情况并已经降低了bug的占分比,但……我也不知道咋改了(弱是原罪orz,dbq)