BUAA-OO-第四单元-UML层次化设计、课程总结

1、第四单元做业架构分析

  面向对象-UML层次化设计

更多参考:http://www.javashuo.com/article/p-fgcthskj-da.html
http://www.javashuo.com/article/p-ovmgsvmj-cq.htmlhtml

UML顺序图http://www.javashuo.com/article/p-xnhtilmq-cb.html
UML状态图https://blog.csdn.net/w36680130/article/details/81014032java

  经过StarUMLnotepad++工具查看并总结程序员

 

  UML将类(class)、接口(interface)、方法操做(operation)、属性(attribute)等都视为对象元素(UMLelement),UMLModel容器管理着模型的全部元素算法

    • UMLClass 对应用户所构造的类
    • UMLAttribute 对应用户构造的类的属性
    • UMLAssociation 对应用户构造类之间的关联性
    • UMLAssociationEnd 对应用户构造类互相关联性
    • UMLGeneralization 对应用户构造类的泛化/继承
    • UMLInterface 对应用户构造的接口
    • UMLInterfaceRealization 对应用户构造接口的实现
    • UMLOperation 对应用户构造类的方法操做
    • UMLParameter 对应用户构造类的方法操做的参数

何为模型?

UMLModel描述各类<UML***>类型元素及其关系(一种图数据结构)……图片来自同窗大佬编程

UML与mdj代码解析

    • 一个项目有一个Model容器,容器下直接有多个类和接口
    • 每一个类和接口下有孩子元素,其中Operation元素下还有Parameter元素,Association元素下有AssociationEnd元素
    • 每一个元素一般有成员_parentId, _id, _type, name, type, visibility, direction, source(源类), target(目标类), reference(相关的两个类,正常状况分两个end元素), navigable(关联方向)等property
    • 类和接口(在mdj代码中属于同一级别)的parentId老是一致的,而且类和接口的parentId为Model的id(parentId不表明任何泛化,关联等意义,仅表明层次结构关系,全部类和接口的parentId都是一个)
    • 那么如何肯定顶级父类?
      利用id进行递归查找,或者并查集思想,主要是考虑递归边界:顶级父类的Generalization元素为空
    • 必定状况下,生成的mdj代码是具备必定顺序的,类的操做元素和属性元素都承接在类元素后
    • 实际的Operation出如今它本身的Parameter中,为了区分参数和操做,可经过Direction标志是否为return来区分,(void)类型的操做的Direction标志也是return,与具备返回类型的操做区分为type标志

类之间的关系

    • 泛化/继承(Generalization),Java单继承,UML能够多继承
    • 接口(Interface)
    • 接口实现(InterfaceRealization)
    • 关联(Association)是一种拥有的关系,它使一个类知道另外一个类的属性和方法
    • 组合(Composition)是总体与部分的关系,但部分不能离开总体而单独存在
    • 聚合(Aggregation)是总体与部分的关系,且部分能够离开总体而单独存在{none, shared, composite}
    • 依赖(Dependency)表示一个类A依赖于另一个类B的定义

UML:接口能够继承接口,也能够实现接口;
Java:接口能够继承接口,但不能够实现接口。设计模式

类属性和操做的数量

    • 注意区分操做是类的仍是接口的
    • 类B经过继承而自动得到父类A的全部属性和操做(只是子类不能直接访问父类私有属性),所以
      B.attriCount = A.attriCount + B.self.attriCount (rule 1)
      B.operaCount = A.operaCount + B.self.operaCount (rule 2)
    • 接口实现不会创建任何上层和下层在属性、操做和关联关系数量上的链接。类有多少属性/操做/关联时,能够直接无视接口实现关系。

关联关系

对于关联下的元素

    • 一种是互相关联Association 关联正常状况下会有两个end元素,都是AssociationEnd类别
      • multiplicity对应的是该关联端对应的个数
      • reference表明UMLAssociationEnd所对应的类的id
    • 另外一种是直接关联Directed Association
      • navigable(关联方向),reference同上,navigable为false(未打勾)的时候表明指向类,为true(打勾)时表明可被指向类
      • 聚合aggregation
    • 两个类关联时,关联信息出如今其中一个类中,另一个类须要经过Reference判断是否被关联
    • 关联有两个端点,每一个端点能够有一个基数,表示这个关联的类能够有几个实例。
      0..1 表示能够有0个或者1个实例
      * 表示对实例的数目没有限制
      1 表示只能有一个实例
      1..* 表示至少有一个实例
    • 在代码层面,被关联的类B以类属性的形式出如今类A中,也多是关联类A引用了被关联类B的全局变量。
    • 在Java中,关联关系是使用实例变量来实现的,类定义
    • UML和Java一致性:类可以和其余类或者接口相关联,接口也能够

关联性是否会被继承下来

答案是确定的,子类拥有父类的全部关联关系,类能够自关联,自关联至关于两次关联
F.assoCount = D.assoCount + F.self.assoCount (rule 3)缓存

依赖

    • 依赖关系时是单向的,也是弱关系,在代码层面,A类中使用到了B类,类B做为参数被类A在某个方法中使用
    • 在java中,依赖表现为:局部变量,方法中的参数和对静态方法的调用。

聚合关系是关联关系的一种,是强的关联关系

组合关系是关联关系的一种,是比聚合关系还要强的关系

UML与Java具备一致性

    • 一个非抽象类必须实现接口中定义但未实现的全部操做
    • 一个类能够实现多个接口
    • 实现类须要显式列出要实现的操做,而继承则不须要显示列出父类的操做

将每一个类和接口做为根节点创建树结构

实质上,UML层次已经显示出来了,经过ref(隐式指针)和_parentId来链接各个树结构造成森林安全

顺序图Sequence Diagram -> UMLCollaboration

  collaboration和Model同层次,Role与interaction(交互行为)为该顺序图的上层,拥有如下的交互对象,sequence,participant 参与交互的对象数据结构

功能:获取参与对象数,获取消息数,获取对象的进入消息数多线程

    • UMLLifeline 生命线
    • UMLMessage 消息传递
    • UMLEndPoint 顺序图终结点

计算总的参与对象

每条生命线对应一个对象

计算总的交互消息

UMLMessage的数量

计算制定对象的incoming消息

接收到的消息数量

顺序图与mdj代码解析,并创建关系图

    • UMLInteraction的下一层有UMLLifeline,UMLMessage

状态图StateChat Diagram -> UMLStateMachine

  StateMachine和Model同层次

状态图表示一个类的行为,功能:获取状态数,获取状态机转移数,获取后继状态数

    • UMLRegion 状态图范围,包括状态和转移信息
    • UMLState 在UMLRegion下一个层次
    • UMLPseudostate 初始状态,获取kind可获得initial标志
    • UMLFinalState 结束状态
    • UMLTransition 和UMLState同一个层次
      • UMLEvent 转移的响应事件
      • UMLOpeaqueBehaviour 状态转移的结果

状态的计数(包括初始和终态且只算做一个)

UMLState元素,可直接得到状态名称

一个状态的不一样的后继状态(可达的状态,一样包括初始和终态,且只计算一次)

又是一个递归建图的问题,经过该状态UMLTransition元素查找
只要可达的状态都算后继状态,注意处理同名同类型的状态(有可能同名但不一样类型)

状态转移计算

UMLTransition元素,source&target
- triggers中的UMLEvent 表明转移触发条件,可从UMLEvent元素中得到转移标志名称

状态图与mdj代码解析,并创建关系图

    • 顶层UMLRegion,其parent_id为UMLStateMachine
    • 下一层有UMLPseudostate,UMLState,UMLFinalState,UMLTransition
    • UMLTransition的下一层有UMLEvent

模型有效性与一致性问题

具备UML检查规则,即应当知足状态图自身、顺序图自身、类图自身、三个图之间的对应规则

UML基本标准预检查功能
- UML002:不能含有重名的成员。针对类图中的类(UMLClass),其成员属性(UMLAttribute)和关联对端所链接的UMLAssociationEnd不能有重名
- UML008:
不能有循环继承。
该规则只考虑类的继承关系、类和接口之间实现关系,以及接口之间的继承关系。
- UML009:任何一个类或接口不能重复继承另一个接口。该规则考虑类之间的继承关系、接口之间的继承关系,以及类对接口的实现关系,包括直接继承或间接继承。

 


 

第一次做业——UML类图解析

任务

  实现一个UML类图解析器UmlInteraction,能够经过输入各类指令来进行类图有关信息的查询。

  查询指令:模型中一共有多少个类、获取类中指定类型的操做(本类本身定义的)数量、类中的属性有多少个、类有几个关联、类的关联的对端是哪些类、类的操做可见性、类的属性可见性、类的顶级父类、类实现的所有接口、类是否违背信息隐藏原则。

设计思路

  UML交互接口的实现类MyUmlInteraction
* 经过className创建树结构,每一个class对本身类进行相应的计算
* 经过className映射类元素
* 经过元素自身id映射元素(id不会重复的原则)

架构设计

基础层

  • MyUmlInteraction 交互接口的实现类

数据结构层

  • ClassTree 类结构树。经过className创建树结构,并对树结构内进行相应计算

  * 一个项目有一个Model容器,容器内有多个类、接口等
  * 每一个class下有孩子元素,其中Operation元素下还有Parameter元素
  * 每一个元素都有成员_parentId, _id, _type, name, type, visibility, direction, source(源),
  * target(目标), reference(相关的两个类,正常状况分两个end元素), navigable(关联 方向)等property

  • InterfaceTree 接口树,功能同ClassTree类
  • AssTree 关联树,仅保存关联对端,而忽略类自己
  • OperaTree 操做树

缓存计算层

  • MyUmlInteraction类经过关联其余数据结构类,当数据结构创建后得到数据结构得出计算结果并保存,方便下次查询。

应用层

  • UmlInteraction类图指令查询功能的接口

Debug

  本次做业的bug:并不保证输入元素具备顺序性,id是惟一区分元素的标志,类和接口会同名(java中不一样包内容许),父类和子类的属性可同名不一样可见性。

  容易出错:类实现的全部接口,包括接口的多继承接口,包括同名不一样id的接口也要列出来;继承父类的关联(父类也可能有继承)。

  大多数问题是对类图层次分析不够明确和完全,对mdj代码和UML图型的对应关系没有理解透彻,形成不少考虑没到位,或者理解错误的地方。

度量分析

类图

  自己实现接口的类很少,只有一个实现接口的类,知足用户查询需求。但须要创建数据结构的类很是多,也是本次做业的重点,查询功能的代码不难写,难在创建数据结构和UML层次关系的解析。只要创建好了数据结构,计算结果很容易得出。

   

代码分析

 

复杂度分析

  经过树和图创建数据结构,经过递归或者dfs搜索计算,代码深度和类图层次关系较为复杂。

 

 


第二次做业——UML类图、顺序图、状态图解析及基本规则验证

任务

  在第一次做业基础上,实现一个UML类图、状态图、顺序图解析器UmlGeneralInteraction,能够经过输入各类指令来进行类图有关信息的查询,并可以支持几个基本规则的验证。

  查询指令:除第一次外还有:给定状态机模型中一共有多少个状态、给定状态机模型中一共有多少个迁移、给定状态机模型和其中的一个状态,有多少个不一样的后继状态、给定UML顺序图,一共有多少个参与对象、给定UML顺序图,一共有多少个交互消息、给定UML顺序图和参与对象,有多少个incoming消息、模型有效性检查(针对下面给定的模型元素容器,不能含有重名的成员(UML002)、不能有循环继承(UML008)、任何一个类或接口不能重复继承另一个接口(UML009))。

设计思路

  UML交互接口的实现类MyGeneralInteraction
* 经过className等信息创建树结构,每一个class对本身类进行相应的计算
* 经过className映射类元素
* 经过元素自身id映射元素(id不会重复的原则)

  实质上,UML层次已经显示出来了,经过ref(隐式指针)和_parentId来链接各个树结构造成森林。

架构设计

基础层

  • MyGeneralInteraction 交互接口的实现类
  • UmlRule002 规则检查类
  • UmlRule008 同上
  • UmlRule009 同上

数据结构层

  • ClassTree 类结构树。经过className创建树结构,并对树结构内进行相应计算

  * 一个项目有一个Model容器,容器内有多个类、接口等
  * 每一个class下有孩子元素,其中Operation元素下还有Parameter元素
  * 每一个元素都有成员_parentId, _id, _type, name, type, visibility, direction, source(源),
  * target(目标), reference(相关的两个类,正常状况分两个end元素), navigable(关联 方向)等property

  • InterfaceTree 接口树,功能同ClassTree类
  • AssTree 关联树,仅保存关联对端,而忽略类自己
  • OperaTree 操做树
  • MachineTree 状态机结构
  • Region 状态机层次结构
  • State 状态树
  • Interaction 顺序图交互结构
  • Lifeline 生命线(交互对象)树

缓存计算层

  • MyGeneralInteraction类经过关联其余数据结构类,当数据结构创建后得到数据结构得出计算结果并保存,方便下次查询。

应用层

  • UmlClassModelInteraction类图指令查询功能的接口
  • UmlStandardPreCheck 规则检查(预先)接口
  • UmlCollaborationInteraction 顺序图交互查询功能的接口
  • UmlStateChartInteraction状态图指令查询功能的接口

Debug

状态图:

  1.计算状态数量的时候初始和结尾状态只算一个

  2.一个StateMachine下保证只出现一个Region,且final和pre状态都只做为一个,且一个Machine中状态不重名

  3.若是初始或者结尾状态是后继状态算

  4.每一个State Machine中,从某个状态到另外一个状态的直接迁移均具备不一样的Event或Guard,即从某个状态到另外一个状态的直接迁移如有多个,则这些迁移必定互不相同。

  5.transition的parentid为region,所以用source。

  6.容易爆空指针以及递归栈溢出,没有处理好递归边界(循环继承的例子)。

顺序图:

    • 对象和lifeline是否对应,多个lifeline能够引用一个对象,但保证Lifeline和其Represent均一一对应。

规则验证:

    • 重复实现也算,经过实现继承也算。
    • associationEnd可能name为空

  大多数问题是对类图、状态图、顺序图层次以及规则分析不够明确和完全,对mdj代码和UML图型的对应关系没有理解透彻,形成不少考虑没到位,或者理解错误的地方。

度量分析

类图

  自己实现接口的类很少,有实现4个接口的类,在第一次做业上增长状态图、顺序图交互、规则检查接口,知足用户查询需求。但须要创建数据结构的类仍然很是多,总共达到13个类,也是本次做业的重点,查询功能的代码不难写,难在创建数据结构和UML层次关系的解析。只要创建好了数据结构,计算结果很容易得出。

 

代码分析

 

复杂度分析

  模型图增长了状态图和顺序图,范围广了,但创建数据结构的方法相似第一次。

 

 


 2、OO做业四个单元的架构设计及其面向对象构造的演进

  第一单元:

  面向对象设计的初步,刚开始还不太会运用面向对象思想编程,对于求导问题仍是很直接地写面向过程的代码。架构设计几乎也没有,很乱,没有交互层面。一次做业仅仅3-4个类:表达式、主函数、求导、数据结构类。

  第二单元:

  多线程程序不只有数据结构类、输入输出类,还增长了与需求交互的类,还有多个线程并发的状况——线程类,还有管理(调度)类。第二次做业逐步体现出抽象的过程,将需求和功能分别对应。

  第三单元:

  JML设计,在这次做业中主要是实现功能接口,也学习到了部分软件工程设计模式(工厂化模式)。这个单元对类的抽象和封装有更高的层次,咱们根据官方接口,实现本身的容器,用于用户查询等操做。在架构设计上,还增长了缓存计算层,将数据层与应用层独立开来。

  第四单元:

  同第三单元相似,只是在数据结构层上增长了深度和难度,结构观察视角和行为观察视角。设计模式和第三单元差很少,都有缓存计算层,实现接口功能的应用层则更好地体现了用户需求与数据的交互,但不会影响数据结构层。

  做业采用了迭代增量的方式每一个单元的三次代码做业,都是基于本来功能进行扩展,增长更多需求和操做。

 


 

3、OO做业四个单元的测试方法与实践(bug修复)的演进

第一单元:

  测试没有太多技巧,主要是经过肉眼观察表达式匹配的字符串,以及碰撞边界特殊表达式的状况,同时,手写评测器疯狂对代码进行测试,虽然效率增长了,但很难保证测试范围和测试质量。

第二单元:

  本单元加入多线程,调试难度加大,甚至没法用断点调试以及找出死锁问题。做业的调度算法增长了难度,须要考虑时间优化,因此逻辑上、优化上出现了不少问题。线程调度、线程安全是测试的重点,但测试方法没有找到很合适的。对于输出结果能够利用对拍器自动比较。

第三单元:

  经过学习JML语言后,运用jmlunitNG等工具编写测试类进行代码测试。这个单元的bug主要是第三次做业,需求增长到四个计算,显然不少Bug,中测倒数第二个最后关头都没找出来,因此没进互测,而后时间复杂度特别高,对于强侧的数据,简直爆炸了。

  修复过程当中,改进了求最短路的算法,修复了超时的问题。对于最低票价和不满意度是最容易存在Bug的,而对于并查集求解基本没有问题。最低票价我采用上文的思路,仍会出现问题,有这几种:单条路径存在环路须要更新权值;每条路径都须要求最短路;新增路径与原有路径存在相同节点也须要更新。

第四单元:

  学习了UML模型图以及运用starUml工具进行模型图构建、生成mdj代码,方便观察和测试,同时可使用前几回做业的测试方法和测试类。

 


4、OO课程收获与体会

  学期刚开始,甚至还没开学(还在家里)的时候咱们就接收到本学期面向对象课程预习做业的通知,我也是本学期才接触到Java编程及其面向对象编程思想,整体上的感受就是,这门课程让我从一无所知变成学会了不少编程思想、测试、调试、架构设计、多线程、软件工程设计模式等方法(不过我依然是一个菜鸡)。那么具体来讲一下这门课程中个人收获,以下:

  一、熟练掌握Java语言及其IDEA编译器的使用。虽然一个学期的时间很短,可是课程任务不是通常的重,而是超乎常人的重。每周都有相似于大做业、大工程的代码项目,那就是必须在每周前三天较好、较快地完成代码编写、调试和经过基础测试,在经过基础测试后,接着两天内进行同窗之间的匿名互测(互相hack,我学会如何作一名hacker哈哈),最后官方评测系统再根据较强测试进行评分,最后还有几天的bug修复环节。除此以外,每两周有一节上机实验课和一节研讨课,每一单元做业完成后对单元做业进行总结的博客编写(例如如今写的就是)。对于咱们来讲,每周都是紧张的状态,每周的代码量也都充足,因此短短地一学期,可以熟练运用IDEA和Java面向对象设计是一大收获。

  二、我的的自学能力和思惟能力获得提升。我我的(或者说大多数人)在这门课程的做业上花费的时间应该是最多的了,这门课程也是最烧脑、最磨时间的课程了。每一个人对程序、工程都有本身的独立思考和转化,能完成这些代码量的程序说难不难,说易也不易,也挺佩服你们的毅力。

  三、课程带来了面向对象编程思想和软件设计模式这些新编程方法。这些思想方法更贴近软件的设计和用户的需求,掌握多种设计方法,可以让咱们(程序员)更好地应对客户需求。一开始从面向过程编程到面向对象编程不免会有不适应,没法理解类的封装与独立,熟练以后,以为每一个功能、每一个类别的东西独立开来,还能够互相交互更方便设计。之间加入多线程则更是符合实际生活需求,生活中多线程的例子不少,滴滴打车,银行排队等,这些也在实验课中完成过,多电梯多调度做业也编写过。

  四、掌握多种程序测试方法及其本身编写评测器还有bug修复方法。写程序固然少不了测试,谁的程序都避免不了出现bug,bug修复也是一个难题,甚至连bug在哪都有可能找不到。课程增长了同窗之间的hack,不只须要找本身代码的bug也要构造测试用例找别人的bug,在此过程当中也学会了编写基本的对拍器,自动评测器,加快hack效率和质量。在学会jml以后,还运用jmlunit等测试类工具进行测试代码。bug修复不比写代码花的时间少,其实写完代码后发现连基础数据都过不了很正常,如今的程序代码复杂度高,肉眼没法再观察获得了,只能经过调试、结果输出、猜测断定等方法找出bug。

  五、如何在短期内写出上千行代码(哈哈哈,这多是程序员最骄傲的收获了,一周内写了上千行代码,是又想吐槽又骄傲又秃头~警告)。

 


 5、OO课程评价与建议

  我对本课程满意度仍是挺高的,虽然确实折磨人,不事后来稍微下降了一点难度,内心畅快多了,以前的多线程单元确实头疼,基础测试都没过。高强度、高难度才能训练出好的工程师,这句话实测无错。

提点建议:

  1. 之后的互测,你们别先忙着写评测机如何如何“坑”别人,这样真的好吗?有的时候全部人平均hack次数2-5次,你一我的上百次(甚至是同一个bug),好玩嘛?纯属找娱乐感和自豪感。其实程序写完美类,彻底不担忧互测的问题,毕竟互测真正的目的是经过本身思惟而不是写评测机自动hack(虽然这个没错)。
  2. 实验课有的时候感受不知道要干吗,或者说实验课作了太多好像没有意义的事。其实实验课没有必要安排在理论课的下一节,毕竟才上完理论课,还没弄明白,接着实验课就作实验,会比较迷茫。
  3. 理论课可能须要更具体更实际一点的讲解,或许有点过大、过宽、过深了。
相关文章
相关标签/搜索