OO第四单元总结

第四单元代码架构

  • 作业架构

    -MyClass
    	-MyOperation
    		-MyParameter
    	-MyAttribute
    -MyInterface
    	-MyAttribute
    -MyGeneration
    	-MyClass
    	-MyInterface
    -MyStateMachine
    	-MyRegion
    		-MyTransition
    		-MyState
    -MyCollaboration
    	-MyAttribuye
    	-MyInteration
    		-Lifeline
    		-EndPoint
    		-Message
    
  • 代码架构如上所示,根据UML本身具有的层次关系建模,通过基于已有的UMLElement包装成新的类,比如MyClass。这样的设计目的是增加原有的类所不具备的属性,以及方法,从而实现满足题目要求。例如在MyClass中含有MyOperation,MyAtribute类型的数组,MyOperation下面又有MyParameter,来实现对层次化关系的建模。通过这样的建模方式,对于指令的查询也就是通过层层调用即可。比如查询类的有关信息,可以直接调用类的方法,类的方法调用过程中又有可能调用到下一级,比如MyOperation的方法,使代码更简洁,层次清晰

  • 在代码实际编写的过程中使用了较多的HashMap,以及HashSet,因为这一次的作业涉及到大量的索引类型的查询,比如通过名字查询以及通过id查询,还有查重等。这个时候使用Hash类的容器可以使得代码更加简单。

    • 比如名字查询,并且要能实现有名字重复就报错,可以利用HashMap很简洁的实现:
    private final HashMap<String, UmlLifeline> name2LifeLine = new HashMap<>();
    
    public void addLifeLine(UmlLifeline umlLifeline) {
            id2LifeLine.put(umlLifeline.getId(), umlLifeline);
            if (name2LifeLine.containsKey(umlLifeline.getName())) { 
                name2LifeLine.put(umlLifeline.getName(), null);
            }
            else {
                name2LifeLine.put(umlLifeline.getName(), umlLifeline);
            }
        }
    
    //查询有关名字对应的umlLifeline,如果不含有key就是不存在这个名字,如果有key但是为null,就说明是重复
    if (!name2LifeLine.containsKey(lifelineName)) {
                throw new LifelineNotFoundException(interaction.getName(), lifelineName);
            }
            else if (name2LifeLine.get(lifelineName) == null) {
                throw new LifelineDuplicatedException(interaction.getName(), lifelineName);
            }
    
    • 利用HashSet,重写equals和hashCode来实现Operation查重:利用两个容器一个Arrilist一个HashSet,如果两个size不一样说明有重复。
    @Override
        public boolean equals(Object obj) { 
            if (!(obj instanceof MyOperation)) {
                return false;
            }
    
            if (!operation.getName().equals(((MyOperation) obj).getName())) {
                return false;
            }
    
            if (this.parametersMap.size() != ((MyOperation) obj).parametersMap.size()) {
                return false;
            }
    
            HashMap<NameableType, Integer> other = ((MyOperation) obj).parametersMap;
    
            for (Map.Entry<NameableType, Integer> entry : parametersMap.entrySet()) {
                NameableType key = entry.getKey();
                int value = entry.getValue();
                if (!other.containsKey(key)) {
                    return false;
                }
                if (other.get(key) != value) {
                    return false;
                }
            }
    
            return true;
        }
    
    @Override
        public int hashCode() {
            return Objects.hash(operation.getName());
        }
    
  • 对应较为复杂度的查询功能,比如关机状态查询,循环继承等,都是通过dfs算法实现。由于这次作业的数据量不是很大,所以dfs的时间空间代价在合理范围内,并且通过递归的方式实现,可以在递归的时候同时修改有关的数据,使得下次再递归到的时候可以直接返回上次递归的结果,从而减少递归的次数,以及多次查询相同元素的代价

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

  • 第一单元 表达式化简
    • 第一单元主要是为了让大家体验面向对象中的层次化设计,因为表达式中天然存在着表达式,项,因子等层次化关系,所以可以利用面向对象的思维很好的包装起来,在解析的时候自顶向下的解析,递归下降
  • 第二单元 多线程电梯
    • 第二单元的内容难度较大,主要是学习多线程的有关知识,需要解决互斥同步的关系,主要的方法就是利用锁。此外这一个单元中更加体会到了增量开发的要求,从第一次到第三次作业出现了横向电梯,横纵方向的请求等等,我们需要尽可能在不改变已有架构的前提下实现增量开发,这就考验了我们的代码设计能力
  • 第三单元 JML
    • 这个单元主要学习有关JML的知识,能够通过阅读JML来实现需求者的需求,并且保证代码能满足规格,体会到了规格化设计的严谨性
  • 第四单元 UML
    • 这个单元继续学习面向对象中的层次化设计,新增加的内容就是学习UML模型,理解UML模型中的层次化设计理念。

测试理解与实践演进

  • 第一单元
    • 主要利用python的numpy库直接来实现正确性检验,然后利用正则表达式来生成数据,生成数据的时候也采用了层次化的细想,基于形式化表达式来自下往上的生成表达式
  • 第二单元
    • 第二单元主要是通过手动构造一些数据来测试,但是由于多线程输出的不确定性,在用肉眼判断正确性的时候出现了错误,导致了一些bug
  • 第三、四单元
    • 主要是利用生成随机数据和指令,和同学对拍的方式,并且记录运行时间

课程收获

在四个单元的学习中,学习了java语言的使用,面向对象的有关设计思想,多线程有关的知识,基于规格的编程,UML模型的有关知识,同时在写作业的时候还收获了一些课外知识。比如在第一单元中学习了递归下降的有关知识,在第二单元中学会了生产者消费者模型,单例模式的使用来简化对象共享问题,第三第四单元中复习了图论有关的算法,比如最短路径,环等等。并且在OO学习的过程中始终严格要求代码风格,所以养成了在写代码无论是python还是C,都维护良好的代码风格,注意代码的架构以及可维护性等的习惯

改进建议

  • 减小作业代码的量,每周一个大作业并且实现代码迭代开发对于我来说还是压力太大了,尤其是每个单元的第一次作业,都很难很快的掌握这个单元的要领,花费大量的时间与经历。感觉整个学期不是在写OO就是再检测OO
  • 希望能提供更多的测试样例,以及加强一下公开的测试数据的强度。因为在每次OO的作业中,在强侧之前都无法获得很多有关代码的正确性的反馈,这给正确性检测带来了极大的难度,导致用来测试的时间甚至超过了代码本身编写的时间,然而这门课学习的是面向对象的思维,而不是如何用python生成测试数据,这样多少有点舍本逐末,并且花费学生更多精力
  • 降低互测和性能分的占比,以及取消能扣别人的分这一制度,可以自己能加分的,但不应该扣别人的分,北航本就内卷严重,何必搞得更乌烟瘴气。
posted @ 2022-06-28 14:05  马曦迪  阅读(16)  评论(0编辑  收藏  举报