OO 第四单元博客作业

第四单元架构设计

类图

  • 4_1

     

    • 第一次作业比较简单,只需要解析类图;

    • 对于解析,需要对类图中每一种元素解析,需要用到 instanceof 判断 UmlElement 类型。

  • 4_2

     

    • 较第一次增加了对顺序图和状态图的解析,与第一次基本同理;代码细节较多,但是逻辑上理解不困难。

  • 4_3

     

    • 增加了对三种图的合法性判断

    • 本次作业中涉及了大规模的重构,因为之前三种图的所有元素都存在 MyImplementation 中,本次作业仍这样处理会很麻烦,因为不能分图的类型去判断相应异常,而且会造成类超过 500 行

 

架构分析

需求理解

本单元要求实现的是 UML 解析器,即对类图,顺序图和状态图的 .uml 文件中提取出特定的信息,支持处理不同的异常类型和判断其合法性等。

实现思路

三次作业的需求是逐渐增加的,且思维难度不高,逻辑性强,我认为是四个单元中过渡最平滑的一个。

核心问题是如何判断什么种类的 UmlElement 需要自行封装。我的理解是,逻辑上包括(或者说拥有)其他元素的元素需要自行封装,如 UmlClass 中有 UmlAttributeUmlOperation,但是官方包中并未给出 UmlClass 直接获取这两者的方法,这就需要我们通过在 MyImplementation 类中实现相应的解析之后,才能够找到并存储这些元素的父子关系。写代码时经常需要下面三张图:

  • 类图:

 

  • 顺序图:

 

  • 状态图:

 

对方法调用的处理也很重要。比如在第三次作业中,我把三种图都封装成了相应的类,对于 MyImplementation 并不是实际存储了这些 UmlElement 解析后的内容,逻辑上他更像是一种提供交互的接口,如对于 getClassOperationCouplingDegree 的实现:

  • MyImplementation 中:只调用 classDiagram 的同名方法

    @Override
   public List<Integer> getClassOperationCouplingDegree(String className, String methodName)
           throws ClassNotFoundException, ClassDuplicatedException
          , MethodWrongTypeException, MethodDuplicatedException {
       return classDiagram.getClassOperationCouplingDegree(className, methodName);
  }
  • classDiagram 中:处理类名对应的异常后,直接调用该 className 对应的类的同名方法

    public List<Integer> getClassOperationCouplingDegree(String className, String methodName)
           throws ClassNotFoundException, ClassDuplicatedException
          , MethodWrongTypeException, MethodDuplicatedException {
       classCheck(className);
       MyClass targetClass = classes.get(className).get(0);
       if (targetClass.checkWrongType(methodName)) {
           throw new MethodWrongTypeException(className, methodName);
      } else if (targetClass.checkSameParaList(methodName)) {
           throw new MethodDuplicatedException(className, methodName);
      }
       return targetClass.getOperationCouplingDegree(methodName);
  }
  • MyClass 中:基本实现这一方法的内部逻辑,但是需要调用 MyOperation 的同名方法,最终返回结果

    public List<Integer> getOperationCouplingDegree(String methodName) {
       List<Integer> res = new ArrayList<>();
       if (!name2Operations.containsKey(methodName)) {
           return res;
      }
       for (MyOperation op: name2Operations.get(methodName)) {
           res.add(op.getCouplingDegree(umlClass));
      }
       return res;
  }
  • MyOperation 中:实现最底层逻辑,返回结果

    public int getCouplingDegree(UmlClass umlClass) {
       int res = 0;
       HashSet<String> set = new HashSet<>();
       for (UmlParameter parameter: parameters) {
           if (parameter.getType() instanceof ReferenceType) {        
               String referenceId = ((ReferenceType) parameter.getType()).getReferenceId();
               if (!set.contains(referenceId) && !referenceId.equals(umlClass.getId())) {
                   res++;
                   set.add(referenceId);
              }
          }
      }
       return res;
  }

 

对所有单元的总结

架构设计思维

  • 第一单元的主题是表达式的解析和计算。本单元很好的利用了 Pre 中学习到的面向对象特性。难点在于对递归下降的实现和理解,即“表达式-项-因子”这一结构。比较有意思的扩展是自定义函数和求和函数,我是利用类似现实中“代入未知数”的处理方式,即用实际参数替换形式参数,这样实现的难点不在于字符串替换,而是要解决括号嵌套。第三次作业的需求恰好就是支持括号嵌套,这也提醒了我好的架构不仅仅会避免大规模重构,更会让后续的迭代方便很多。

  • 第二单元的主题是多线程电梯调度。现在来看,这一单元思维难度其实不大,重点在于对 java 中线程的理解。如何合理地设置同步块、调用 notifyAll()、如何避免死锁和轮询......等等,对于这些问题的处理,很大程度影响了本单元作业的正确性与性能。本单元我也学习并应用了较多的设计模式,体会到了其功能之强大,如利用单例模式创建调度器避免其作为参数多次传递、利用工厂模式更方便的创建不同的电梯对象,利用消费者-生产者模式理解电梯与乘客、调度器的关系等。

  • 第三单元是实现社交网络系统。本单元其实不用深入理解项目需求是什么,很多地方根据 JML 规格就可以编写出正确的代码。

  • 第四单元是实现 UML 解析器。本单元最好地诠释了面向对象中封装性的强大。这一单元要求我们精确地理解 UML 模型中各个元素的含义和父子关系,引入了属性耦合度、继承深度等概念进一步提高要求。什么时候需要封装?如何进行方法调用会尽可能地方便?这都要求我们对封装性有深刻的理解。

 

测试

  • 第一单元涉及数学知识,可以很方便的手动构造边界数据;

  • 第二、三单元更适合编写数据生成器生成随机数据+对拍进行测试。其中,第三单元的逻辑非常适合自行搭建评测机。

  • 第四单元虽然也适合写评测机,但是逻辑上难度不大,细节上问题较多。更适合采用 JUnit 手动测试

 

课程收获

  • 让我第一次认识到了不需要系统学习编程语言的语法(虽然 Java 语法也不是这门课的重点),也可以写出正确且可读性强的代码(可能是IDEA功能太强了?

  • 在本门课程中完成了面向过程到面向对象思维的转变,最明显的就是从最开始在第一单元使用 public static xxxx 方法作函数,到最后第四单元对不同函数进行不同层次的调用和封装。

  • 认识到了测试和 bug 修复的重要性。既不要忽视细节,也不要过分注意细节导致大局观出现问题。

  • 认识到了规格化设计的重要性。如利用 JML 语言实现对前置条件,后置条件等的预先考虑。

  • 可以自行完成类图、顺序图、状态图的绘制,并深刻理解了他们的概念与意义。

  • 可以使用 git 完成代码版本管理。

  • 复习了图论的一些算法,对于算法和数据结构的理解更深一步。

 

课程改进建议

  • 可以多增加一些业界大佬讲座,想听更多前沿的并有实际应用价值的知识。

  • 课上对作业需求的解读较少。很多时候都是课上的内容可以理解,但是对作业一开始总要蒙一段时间,不知道如何应用课上知识。而且作业内容都是放在每次课的最后讲,用时很短。

  • 对于开学初因为疫情等原因未返校上课的同学不友好。虽然提供了课程录音和课件,但是还是缺少在学校时的氛围。信息渠道少的同学开学时完成作业很吃力。

posted @ 2022-06-29 03:14  WassuhJ  阅读(41)  评论(0编辑  收藏  举报