BUAA_OO_UNIT4
总结本单元作业的架构设计
第一次
这次作业要求实现UML类图解析
因为和Java的类类似,因此我设计了MyClass,MyInterface,MyOperation。
其中MyClass中封装了自己的属性、自己的方法、实现的接口
MyInterface中封装了自己的父接口(包括爸爸的爸爸)
MyOperation中则有判断方法是否含参、返回值的类型、参数类型、返回值类型
由于参数都是查找,因此我在涉及到的类中都加了缓存,如果是第一次查询,就搜索并且将结果存入该类的属性中,把isQuery设置为true;后续查询直接在缓存中查找即可
例如
@Override
public int getClassAttributeCount(String className) throws
ClassNotFoundException, ClassDuplicatedException {
MyClass myClass = checkClass(className);
boolean isQuery = myClass.getQueryClassAttributeCount();
if (isQuery) {
return myClass.getClassAttributeCount();
} else {
int attributeSum;
attributeSum = myClass.getSizeOfAttribute();
String id = myClass.getId();
while (childClassId2generalization.containsKey(id)) { // 还要找它父类的属性
myClass = id2class.get(childClassId2generalization.get(id).getTarget());
id = myClass.getId();
attributeSum += myClass.getSizeOfAttribute();
}
myClass = name2class.get(className);
myClass.setQueryClassAttributeCount(true);
myClass.setClassAttributeCount(attributeSum);
return attributeSum;
}
}
第二次
这次作业相比于第一次增加了时序图和状态图,对比于第一次的代码,我把大部分查询工作放到了每个类自身中(比如getParticipantCount(String interactionName)
,我在MyInteraction中增加了同名的无参方法)这样既可以在顶层类中减少代码量,使代码看起来更加简洁,还符合了高内聚低耦合的思想,使debug的工作量大大降低。
MyUmlGeneralInteraction类中的方法
public int getParticipantCount(String interactionName) throws
InteractionNotFoundException, InteractionDuplicatedException {
MyInteraction myInteraction = checkInteraction(interactionName);
return myInteraction.getParticipantCount();
}
MyInteraction中的方法
public int getParticipantCount() {
return id2lifeline.size();
}
并且为了让文件行数符合CheckStyle的要求,我把输入的解析放到了一个单独的类中,并且设置静态变量和静态方法。
public class MyParse {
private static final HashMap<String, MyClass> ID2CLASS = new HashMap<>();//id到class的索引
private static final HashMap<String, Integer> NAME2CLASS_COUNT = new HashMap<>();
private static final HashMap<String, MyClass> NAME2CLASS = new HashMap<>();//类名到class的索引
private static final HashMap<String, UmlAssociationEnd> ID2ASSOCIATION_END = new HashMap<>();
private static final HashMap<String, UmlGeneralization> CHILD_CLASS2GENERALIZATION
= new HashMap<>();
public static void parseElements(UmlElement... elements) {
for (UmlElement element : elements) { // 对每个element解析
parseElementFirst(element);
parseElementSecond(element);
}
}
}
自己在四个单元中架构设计及OO方法理解的演进
UNIT1
第一单元中,我对面向对象的思想的理解还比较浅显,第一次作业是完全的面向过程。后两次作业,我逐渐理解了面向对象的思想,将表达式自顶向下解析,每个类只要完成自己的工作而不需要关心其他部分的工作,而在主类中将每个类的工作组织起来,就可以完成整个工作,我认为第一单元的学习过程中我对OO的理解是从无到有的进步,比后面三个单元的进步都要大。
UNIT2
第二单元中,由于第一次接触多线程编程,前两次作业我的作业架构设计都显得并不是很面向对象。而在第三次作业,我重新梳理的作业的要求和我要实现的功能和构想的架构,并且加深学习多线程编程,我的代码的架构又更加面向对象,与此同时,也通过了所有点。通过这单元的学习,我明白了架构设计的好,真的可以在性能和正确性上都提升很多。
UNIT3
这一单元是照着JML写,是整个学期OO课程中体验最好的,但是由于第一次我没有考虑性能,强测直接挂了5个点。这一单元中我学到的是,要深刻立即要求的设计目标的内涵(最短路径等),从而选择合适的数据结构和算法来表示,而不能单纯的对设计一句一句的“翻译”,不仅性能差,正确性也难以保证。
UNIT4
这一单元学习了UML类图,通过解析UML类图的方式,我理解了层次化的重要性。通过层次化将复杂的类图解析,将抽象的UML表述转化为具体的逻辑关系。
自己在四个单元中测试理解与实践的演进
这四个单元我的测试方法基本一致:
1手动构造
2自动测试程序
第三单元则主要是对拍,进行碰撞
综合来看,程序自动生成随机数据是最轻松的方法,但是往往要跑很久才能测出一个bug,并且无法确定清除bug后的正确性
效率最高的是手动构造边缘数据,这种方法不仅能找到程序的bug,对理解程序也有很大的帮助,我在这方面的能力较弱,以后应该多家尝试
自己的课程收获
面向对象思想的建立
通过OO课程的学习,我建立了面向对象的思想,尤其是第一单元突如其来的难度。
Java语言的深入学习
在OO课程之前,自己从未接触过Java,而在OO课程中,我不仅是学习了Java代码的编写能力,对Java内部已经实现的容器类(如HashMap)的方法如何提高效率也有了一定的了解。这里要感谢助教哥哥张家树,之前从来没有考虑过这里也会对程序的性能产生影响。源码的阅读在很多时候是必要的。
自动测试程序
在上学期的计组课程中就有很多同学使用了自动测试程序,而我由于对命令行的陌生,一直都没有尝试。这学期的OS课程让我对命令行有了写了解,在自己编写测试程序时考虑如何增加边界数据,对自己编写代码和debug的能力都有很大的提高。
看似很小但却有用的小知识
markdown的使用,git的使用,不仅在OO课程中使用,在平时我也养成了使用git的习惯
改进建议
希望实验课有答案
第四单元的难度明显大于第三单元,而第四单元却进入了考期,可以考虑换一下顺序?
题目可以适当更改,但是每年递增有点搞心态