OO UML总结暨课程总结

OO UML总结暨课程总结

1、架构分析

两次UML解析程序,主要是递进式的,第一次解析了类图,第二次在类图基础上,增长检查规则和顺序图及状态图。java

整体架构思路主要有五点:算法

一、尽可能还原图自己的结构(组装)json

二、分类(状态图、顺序图、状态图)设计模式

三、元素与关系分离安全

四、对同一类element进行合并数据结构

五、抽象Element多线程

 

先从类图来说:架构

一、还原框架

每一个class有attribution、operationide

每一个operation有parameter

所以有

UMLPARAMETER-->UMLOPERATION + UMLATTRIBUTION -------> UMLCLASS

对接口有相似操做,继承Class便可

简单的画个类图他们关系大概就是这样

 

咱们只需经过json中的_parent和id就能够把他们联系这一块儿,至此重组完成。

 

针对第二次解析程序这里有一些小改变(元素重名检查):

因为类图检查须要检查Class对端的asscociationEnd与自身Attribution的重名问题。也就是说associationEnd也会属于Class,所以AbstractClass中的内容须要增长asscociationEnd的存放(只需增长一个容器和规则检查方法,总体难度不大,算是作了一次小拓展)

 

二、关系与元素分离

关系主要是类之间的,有继承、实现、关联。

因为UMLClass是咱们元素组装的最上层,天然关系与其同层次,放在任何一个里面都不太合适,所以选择了将他们分离的策略。

咱们单独创建一个Relation来存放他们。

解析json-->识别type-->分类存放 便可。

 

针对第二次解析程序这里有一些小改变(关系检查):

不管是循环继承的检查仍是重复继承的检查,都整合了这两种关系(继承、实现),所以为了操做方便,这里选择增长一个RelationCheck类,构建一个继承和实现关系构成的图。而后用上各类搜索方法(如DFS)就能够轻松解决上述检查。

 

由此能够看出,在这种架构之下,两次解析程序的递进针对类图都不会出现重构的状况,只需作少许拓展,便可完成。

 

再讨论下状态图

一、还原

跟类图同样,按照层次关系:(关系比类图要简单点)

UMLState + UMLTransition --> UMLReion --> UMLStateMachine

重组便可

public class AbstractStateMachine {
   private String name;
   private String id;
 
   //Region
   private String regionId;
   
   // UMLTransition
   private HashMap<String, UmlTransition> idToTranstion = new HashMap<>();
   private HashSet<AbstractTrans> transHashSet = new HashSet<>();
   
   //UMLState
   private HashSet<AbstractState> states = new HashSet<>();
   private HashMap<String, AbstractState> idToState = new HashMap<>();
   private HashMap<String, ArrayList<String>> nameToState = new HashMap<>();
   
   //RELATION
   private HashMap<AbstractState, HashSet<AbstractState>> transRelation
           = new HashMap<>();
   private HashMap<AbstractState, Integer> idToSubCount
           = new HashMap<>();

可能会发现Region怎么彷佛和State平级,主要是因为Region实在对查询功能无大用,更像是StateMachine的傀儡???

二、合并

这是我针对本次做业想重点讨论的话题。

也是我认为本次设计成功的点之一:为了易修改,易拓展而设计

 

State

状态机中有三类状态:UmlFinalState、UmlPseudostate、UmlState,状态统计须要考虑这三者,同时状态转移也是在这三者中进行,所以咱们能够采用一个AbstractState类来代替这三种。

public class AbstractState {
   //0: state -1:init 1:final
   private int type;
   private String name;
   private String id;
   
   public AbstractState(int type, String name, String id) {
      ...
  }
   
   @Override
   public boolean equals(Object obj) {
       if (obj != null && obj instanceof  AbstractState) {
          ...
      }
       return false;
  }
   
   @Override
   public int hashCode() {
       return type;
  }
  ...
}
   

这样作有良好的可修改性,咱们能够自行定义,什么是共同状态?。

好比针对以前一直比较有争议的是否合并起始状态等问题,只需修改重写的equals方法便可。

 

一样,对Transiton也采用一样的方法。

package stategraph;

import java.util.ArrayList;

public class AbstractTrans {
   private String id;
   private String name;
   private AbstractState source;
   private AbstractState target;
   private String guard;
   private ArrayList<String> triggers;
   
   public AbstractTrans(String id, String name, AbstractState source,
                        AbstractState target, String guard,
                        ArrayList<String> triggers) {
      ...
  }
   
   @Override
   public boolean equals(Object obj) {
       if (obj != null && obj instanceof  AbstractTrans) {
          ...
          }
           return false;
      }
       return false;
  }
   
   @Override
   public int hashCode() {
       return 1;
  }
 
  ...
}

一样,什么是相同状态,咱们就能够在此定义,一旦规则有变,也只需修改这一处便可。(虽然最后限制了测试数据,这个地方没有了大用)

 

三、分离

在这里,相似于类图中的操做,把转移关系存储为图架构。须要注意的是,因为考虑了合并问题,所以能够经过一个类AbstractTrans来封装它,经过重写equals方法便可实现合并。

 

最后是最简单的顺序图

顺序图整体比较简单。

一、还原

跟类图同样,按照层次关系:

UMLLifeline + UMLMessage ----> UMLInteraction

重组便可

public class AbstractInaction {
   private String name;
   private String id;
   //UMLLifeline
   private HashMap<String, UmlLifeline> idToLifeLine = new HashMap<>();
   private HashSet<String> represent = new HashSet<>();
   private HashMap<String, ArrayList<String>> nameToLifeLine = new HashMap<>();
   //UMLMessage
   private HashMap<String, UmlMessage> idToMessage = new HashMap<>();
   //RELATION
   private HashMap<String, Integer> messageIn = new HashMap<>();
  ...
}

二、关系与元素分离???

(1)Interation跟message是从属关系,不是同层次

(2)查询命令简单,无任何图算法相关操做

所以,这里不采用,只是加两个容器储存和统计一下便可

 

2、架构设计总结及OO方法理解的演进

四个单元对OO的架构设计是从面向过程到面向对象的一个巨大的转变。

第一单元,设计之初过多考虑功能性问题,致使多项式求导的设计很是没有层次感(把因子,项等杂糅在一块儿,经过递归处理,这样很是不OO)

第二单元,电梯的设计主要是多线程的安全性问题。我遇到了比较大的困难,很差的架构致使了线程不安全的可能性增长。可是通过参考多线程各类设计模式,而且把电梯调度分部分考虑,架构有了必定提高,但代码杂糅的程度仍是比较高的。

第三单元,JML部分因为助教提供了一个大致框架,我也更多去思考设计的层面,总体的思路和结构都好转。

第四单元,UML是我考虑拓展性和架构设计优劣性最多的一次。更多注重下一次功能可否垂手可得增长的内容,而且在本身的debug和修改的过程当中,体会到了很是大的好处。

我认为OO设计一开始不能一味考虑算法(功能性)和AC的问题,更多应该聚焦在层次拆解。

以第四次单元为例

(1)设计的最终目的(交互,最高层)

(2)分为哪几个大部分(顺序图,状态图,类图)

(3)对每一个部分,有哪些小部分

主要考虑功能部分和元素部分

例如,状态图的元素有迁移、状态,功能是查询。

针对元素部分作适当有层次的封装(也就是充分展示类之间的继承关系,关联关系)

(4)采用什么样的数据结构??

(5)具体实现算法

其实,只要把(1)-(3)重点考虑(通常能够在纸上画出层次图(如使用UML))

(4)作必定考虑  (5)也就垂手可得了

综上所述

(1)思考和设计大于写码,好的层次必定程度上能让功能设计更加垂手可得。

(2)OO的设计是能帮助更好,更高质量的AC,若是一开始过度考虑AC,反而拔苗助长(惨痛教训)。

 

3、测试的理解

从最开始做业使用手动测试,到多项式的后两次做业开始尝试本身编写评测机制。

从固定结果的验证方法,到多线程不肯定性如何验证正确性的测试编写。

从整体的黑箱测试到Junit作单元测试

从测试正确性到测试运行时间。

上述,大概就展示了我OO中的测试思路的转变(几乎每一次转变都是爆掉几个点以后的痛定思痛)

我认为测试

(1)正确性和运行时间兼顾(保证明现的正确性和使用方法和结构的优良性)

(2)整体测试和单元测试兼顾(我后来采用了边编码边JUNIT的历程,不得不说,正确性更有保障)

(3)自动评测很是重要(利用随机样例去测试,经过较长时间的运行,保证黑箱测试的覆盖率问题)

 

4、课程收获

1、编码能力:经过本学期十屡次做业的练习,做业的规模让本身的代码能力显著提升。

2、抗压能力:屡次临dll修改bug,有成功修改,有不成功修改的,这样的经历确实很是锻炼在短期的修改代码并保证正确的能力。

3、需求分析能力:对指导书的内容进行分析,而且逐渐转化为程序语言。

4、还有对OO的理解和承认,对测试的体会,都是此次的巨大飞跃。

5、建议

1、建议课程组提供自主测试平台:本次测试和评测机测试存在运行时间上的偏差,所以建议给你们开放一个平台,让全部人均可以在上面进行测试,获得运行时间,对多线程以及卡TLE的部分做业很是有帮助。

2、上机内容能够考虑提早发布一些预习任务,这样能让上机时候更加有针对性去应对,不至于手足无措。

3、适当预告后续做业的需求:有利于更好的拓展性设计。

相关文章
相关标签/搜索