第四单元架构设计
整体思路
这个单元的架构设计的思想就是使用代理模式对官方包中提供的各种UML类进行封装,建立自己的MyUml类,并在MyUml类中添加一些UML类所不具有的方法和引用,从而实现对UML模型的建模和快速查询,以及指令的实现。
给出的UML模型中,只有子节点指向父节点的引用,这样非常不利于进行UML元素的查询,因此在建模的过程中,通过多次遍历元素将父节点中以HashMap的形式记录它们的子节点,方便查询。
作业架构图
三次作业的架构都一样, 因此仅以第三次作业的架构为例,这里面MyClass和MyInterface是MyObject的子类,这是因为MyClass和MyInterface有很多相同的属性和方法,同时在UML模型中它们两个几乎可以认为是同等地位的,因此通过继承MyObjec,也可以将MyClass与MyInterface放在同一个容器中,方便查询。
其它的类就没有继承关系了,它们之间的关联存在于每个父UML元素中均持有子UML元素的引用,比如MyOperation中有MyParameter的哈希表。
一些经验之谈
-
建立模型时我首先将所有的元素放在了一个
HashMap<String, UmlElement>
中,这样之后通过子节点查询父节点就是O(1)复杂度了,很方便。 -
解析UmlMessage时切记不可以通过遍历之前建立hash表来实现,因为Uml007要求UmlMessage要按照输入顺序处理,而遍历hash表的顺序大概率不是原先输入的顺序。此时可以直接遍历构造函数中给出的elements数组。
-
可以对方法参数以及方法返回值的类型判断通过建立静态类解决,而不是ifelse,如下所示:
public class NamedTypeIn { private static HashSet<String> set = new HashSet<>(); static { set.add("byte"); set.add("short"); set.add("int"); set.add("long"); set.add("float"); set.add("double"); set.add("char"); set.add("boolean"); set.add("String"); } public static boolean contains(String name) { return set.contains(name); } }
设计思维 与 OO理解演进
第一单元
第一单元是最体现面向对象设计的单元,通过递归下降法建立起了表达式结构,表达式的项和因子等元素有很多继承关系,同时也有很多方法的Overide。在这个单元里,由于表达式本身从面向对象的角度看就很抽象,同时又涉及到了一部分循环继承,因此促使我认真思考了继承,多态等设计思想的应用以及实现方式。
现在看来第一单元应该是我践行面向对象设计最彻底的一个单元,因为好的继承关系可以极大的简化拆括号的复杂度,即通过类之间的关系以及方法调用而不是循环判断语句来实现拆括号。
这一单元中我使用了工厂模式建立不同的表达式元素。
第二单元
这个单元中的面向对象设计主要体现的对象的交互设计中。我认为多线程设计应该分成两个部分考虑:临界区设计以及各个线程独有的逻辑的设计。这两个部分的设计应当是互相没有任何交互的,即对各个线程独有的逻辑而言,这部分代码与单线程代码并无差别。而临界区的设计也不需要考虑各个线程代码的执行情况。这样做可以有效的避免线程不安全问题,同时简化代码逻辑。
多线程程序的开发可以分成四步:
1.确定线程与共享资源的个数与功能
2.不考虑轮询和线程结束的情况下完成各个类
3.找到线程wait的条件,避免轮询
4.加入线程终止逻辑
在完成一步前不用考虑下一步的任务,这样可以有效降低思维复杂度。
这一单元中我使用了生产者消费者模式,读者写者模式来协调多线程交互,以及使用工厂模式创建不同类型的电梯,还有使用了单例模式实例化输出类。
第三单元
该单元的核心思想在于规格设计与代码实现的不一致性。对于同一个规格设计可以又很多中复杂度不一的代码实现,有些实现方式很快,但是很麻烦,有些很简单,扩展性也比较好。这些就需要自己折衷考虑了。
第四单元
第四单元的核心感觉是数据结构???主要复杂度基本集中在建立模型的环节,如果模型建的好,查询就很容易。
对测试的理解
第一单元:使用python编写数据生成器以及评测机。sympy库帮了大忙。不过随机数据的强度不是很强,还需要通过手造测试数据来保证程序的正确性。这一单元还利用了翁英杰同学的java版数据生成器以及张凯歌同学的python版数据生成器,数据生成比我写的强多了orz。
第二单元:使用python编写数据生成器,在程序中导入了学长放在github上的输入解析包进行输入解析,并利用翁英杰同学的正确性检验程序检验输出的正确性。
第三单元:使用python编写数据生成器,并编写了powershell脚本用于自动化对拍。这一单元中还利用了翁英杰同学和王小鸽同学的数据生成。
第四单元:继续沿用第三单元的powershell脚本,同时利用了姜雨竺同学的数据生成器。还从github上寻找了一些数据生成器用于测试。
总结:
oo的测试工作需要众人拾柴火焰高。回顾整个oo课程,我基本上都是组团测试对拍,一个测试团队中的每个人负责编写测试工具的不同部分,最后组合起来进行测试。事实证明,凡是经过认真测试的作业,强测中都没有出现问题,但是有一两次没有怎么测试过的作业,在强测中就会出现一些意想不到的bug。测试工作还少不了强生,陈俊杰,李松泽,王雪竹,高保隆的鼎力相助,这里一并向他们表示感谢。
课程收获
了解了面向对象设计方法,可以用java语言写一些面向对象的程序。同时也掌握了一些多线程程序的设计方法。不过我认为最重要的是对代码能力的提高。代码能力确实需要写很多很多的代码来训练。无论是java作业还是python评测机,每周上千行的代码量对代码能力有很大的提高。同时在自动化对拍中也掌握了powershell脚本的编写方法。
课程建议
-
加强预习,把第一单元的部分内容挪到预习中来,否则开学第一周有点困难。
-
缩短互测开放的时间,建议可以提前一天把同学们的代码放出来,但是互测只开放几个小时,这样可以提高效率。
-
希望指导书中可以增加一些样例辅助理解。