微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

面向对象设计与构造 第四单元总结

面向对象设计与构造 第四单元总结


写在前面

"不知道是谁说的,这第四单元简单,不用往深了思考。我还认真写了3天呢,结果评测连 * * 弱测点都没过......" —— from 泸溪河

哈哈哈哈,上面那句话当然是开玩笑的,不过u1s1,oo课最后一个单元的作业,难度确实有一 xue xue 大。做完这三次作业我最大的感受就是,第四单元的任务很像是没有JML规格引导的第三单元任务,难度出现在对于UML的理解以及架构分析的方法。虽然经过疯狂恶补UML+烤漆抽空爆肝得到了100*3,但是回想起来自己的理解还是存在部分欠缺,测试也不是很全面,代码能过可能也是强测数据点也不是很强?

总之,废话少说,先来反思下我是怎么实现这单元作业的吧。


UML解析器架构设计

一开始看到这份作业,我确实对架构的划毫无头绪,在仔细阅读了课件与官方包组成后,我有了大致的想法:在MyUMLInteraction中进行数据解析、建立数据存储并进行指令实现。解析数据后建立对应的集中数据类型的自建类,并将与其相关的对象存储到自建类的属性中,并在自建类中实现UML查询的相关方法,以供MyUNLInteraction进行调用

第一次作业

一代目结构图如下:

image

第一次作业比较简单,而且只涉及到UML类图相关内容,我就不加思考直接进行实现了。现在看来,大概是当时复习OS看书看傻了......如果这次作业能有类图,后面为啥就不能有状态图和时序图

万事开头难,第一次作业实现的内容其实并不复杂,架构的搭建是大问题。我的这种直接型的架构注定后面的作业需要小重构,读者要以此为戒orz。

方法的实现都不太难,需要注意有情况下需要回溯正在处理的类的父类,并且上溯时注意时间复杂度,能用Map绝对不要用List。比较复杂的方法应该是getClassOperationParamType,说复杂其实也不复杂,只要对类的操作遍历,利用Set进行去重即可。HashSet去重要求元素内信息完全一致,即如果元素包含List,则List的元素排序也得一致,可以排序之后再利用Set去重。

第二次作业

第二次作业实现时还抱有一丝侥幸心理,加上要考离散3,就在原来的烂摊子上继续搭建了。二代目结构图读者简单看看就行,最终实现还得看三代目。

image

第二次作业加入了时序图与状态图的相关指令。主要需要搞清楚各个图与元素之间的关联关系,比如StateMachine-Region-StateInteraction-LifeLine-Message这样。弄清楚什么信息存储于什么类,类与类之间的关系,第二次的指令就不难实现了。

第三次作业

在经过3次作业的代码迭代之后,我预想中的架构逐渐定型成这样:

image

其实也真不是自己想重够,而是第三次要进行UML格式检查,之前的架构与数据存储方式根本无法支持,只得进行更加详细的分类

对迭代之后的代码进行分析,得到的结果也与上图相似:

image

从我个人而言,最后一单元的架构设计难点不在于作业要求,而是在于对UML本身的理解,如果能对不同的UML图有清楚的认识,就可以按照UML分类来进行架构搭建,极大地提升效率。

这三次作业中,由于存在类、接口之间的继承关系,需要特别注意一些非法情况以及注意如何在子类中进行上溯。具体的,每个类只能继承一个父类、继承接口看作实现接口、接口不能继承类...此外,在回溯时需要考虑时间复杂度。

至此,第四单元的分析就告一段落了,面向对象的课程内容也要告一段落了,但是.......结束,但没完全结束一个学期12次的代码作业,也该好好反思下啦。


四个单元中架构设计及OO方法理解的演进

初出茅庐——表达式求导

第一单元的架构其实现在看来很简单不过,核心就是功能的模块化,以及类的分工明确化。通过接口或者类的继承来实现统一的求导方法,每个类维护自己的数据与方法,提供结果与访问的接口给上层类,从而实现“权责明确”

方法上,表达式树递归下降都是比较值得学习的方法。利用树形的结构存储数据,可以更加契合表达式-项的层次结构,也方便结果的长度优化。

精打细算——多线程电梯

多线程由于自己做了大量的预习,对架构的设计思考比较清晰。整个作业可以分为多线程实现与电梯算法优化两大部分。

多线程实现部分,主要就是对生产者-消费者模式的使用,通过线程安全锁或者线程安全数据类保障进程之间的数据共享与数据隔离。

电梯算法方面,要考虑单电梯与多电梯的配合。单电梯主流采用scan算法look算法,捎带算法是课程组的评测基准。多电梯最优的方法可能是自由竞争,也可以面向大量数据进行训练得到相应的分配惩罚系数,来进行统一调度。

在pre中,课程组就帮助我们初步理解了工厂模式,新电梯的加入就可以通过工厂模式实现。此外,Java的23种设计模式也非常值得学习与了解。

笔者第二单元的blog中给出了大量的关于调度以及多线程的内容,详细可以参考那份博客

大意失荆州——JML规格实现

所谓“成也JML,败也JM”,感谢JML让我获得了OO历史最低分orz。JML规格给出了实现的具体方式,只要仔细阅读就能完整写出来,超不超时就另一说了。真就是“编码一时爽,强测火葬场”。

这一单元的代码架构课程组已经给出,具体的实现、坑点得要我们在实现方法时自己摸索。例如查找关联节点,为了减少时间复杂度必须使用优化的Dijkstra算法,可以是搜索方式优化也可以是最小堆优化,这也充分证实了数据结构相关知识的重要性。

痛并快乐着——UML架构解析器

痛在烤漆不得不挤压复习时间完成OO作业,快乐在三次作业都拿了满分。

具体的架构实现可以看本文第一部分,有对第四单元三次作业架构的详细分解。

个人认为这一单元架构实现完全可以按照UML图的种类进行划分,进而在不同的类图对应的类之下实现查询方法,将结果传到上一层。


四个单元中测试理解与实践的演进

从第一单元自己搭建评测机进行黑箱评测,到第二单元进行代码分析Debug,再到第三单元JUnit模块化测试,我对于测试的理解不再局限于拿多组数据看看程序跑的对不对,而是更加富有层次化规范化

第三单元的Network单元测试:

public class MyNetworkTest {
    private Network myNet;

    @BeforeClass
    public static void beforeClass() {
        System.out.println("---before class---");
    }

    @AfterClass
    public static void afterClass() {
        System.out.println("---after class---");
    }

    @Before
    public void setUp() throws Exception {
        myNet = new MyNetwork();
        Person p1 = new MyPerson(1, "Yue", new BigInteger("123"), 19);
        Person p2 = new MyPerson(2, "He", new BigInteger("456"), 21);
        try {
            myNet.addPerson(p1);
            myNet.addPerson(p2);
        } catch (EqualPersonIdException e) {
            e.print();
        }
        System.out.println("---before test---");
    }

    @After
    public void tearDown() throws Exception {
        System.out.println("---after test---");
    }
  
    @Test(expected = EqualPersonIdException.class)
    public void addPerson() throws EqualPersonIdException {
        Person p1 = new MyPerson(1, "YueYang", new BigInteger("123"), 19);
        myNet.addPerson(p1);
    }
}

搭建评测机也帮助我系统学习了一遍python,py的很多库函数在第一单元求导中有很强大的作用。数据生成的思路也得以清晰,主要构造数据可以从边界数据入手,测试覆盖面积要尽可能的全面


课程收获

面向对象这门课应该是进入计算机学院以来,学起来最快乐最认真最有体验感的一门课。

课程节奏虽然紧凑,但是完美复现了程序开发的种种环节,利用多次代码作业帮助我们学习了架构设计、面向对象思想、多手段测试等等内容

不仅如此,代码风格风成功帮我治好了代码不规范的毛病,从一开始checkstyle几乎0分到最后差不多不用check就能100真的进步很大。

完成作业时的自主学习,提高了我学习的效率与能力,也增强了资料搜索与阅读的能力,让我认识到了预习+理解的重要性。


改进意见

  1. 加强假期pre的强度,提供相关预习资料。第一单元大部分同学反应难度梯度增加的比较大,我认为课程组可以从寒假pre中逐渐提升难度,帮助适应开学以来的程序开发。
  2. 第三单元JML部分指导书需要double check。完成第三单元作业时经常收到官方包、指导书更新的通知,在打代码时也感觉到有些地方的规定不是很明确。
  3. 研讨课可以增加集体讨论的形式。这学期的研讨课大部分都是同学在展示,个人认为加一些集体讨论可以拓宽大家的思路,也可以方便老师和助教听到同学们的一些建议。
  4. 每次的课上实验建议公布答案与解析。感觉在不知道成绩与正确答案的情况下做一次实验,得到的效果还不是很好。

致谢 AckNowledgement

在课程中,老师、助教与同学们曾多次在我迷惘的时候热心的给予我帮助,使我得以顺利的完成这门课程并在几乎每次代码作业中得到尚可的结果。

在此,向吴际老师林宇菁学长以及帮助我的各位大佬,送上最真挚的感谢!

终章,亦是序章......

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐