OO_Unit4_UML模型化设计
CSDN博客传送门
@
一、架构设计
(一)第一次作业
本次作业关于UML中的类图。如果说JAVA是用来描述对象及其联系的一种建模语言,那么UML则是用来描述JAVA语言的高层次建模语言,而我们需要完成的作业则是对UML语言的描述及对UML对象的管理。随着层次(此处“层次”并非抽象层次,而是结构层次,高层和底层之间具有组合关系)逐渐地提高,思想的复杂度和抽象性也成倍地提高(需要在多个不同层次去思考问题)。
作业需求分析
- 通过实现
UmlInteraction这个官方提供的接口,来实现自己的UmlInteraction解析器。
由于对象之间的关系无非内涵(组合)、外延(继承)、耦合(联系):
- 用缩进表示结构层次(组合关系)
- 用括号
()表示抽象层次(继承关系) - 用
[]表示指向对象的指针(联系关系):其中必然联系同时是对象中的组合(需要用缩进表示),偶然联系则直接写在对象后面
用对象图来表示这三种关系如下:
- ClassModel
- Interfaces
- Interface(Object)
- Associations
- Association
- [Object]
- Association
- Generalizations(Generable)
- Generalization1(Generable)
- [Interface]
- Generalization1(Generable)
- Implementations
- Implementation
- [Interface]
- Implementation
- Operations
- Operation
- Associations
- Interface(Object)
- Classes
- Class(Object)
- Associations
- Association
- [Object]
- Association
- Attributes
- Attribute
- Implementations
- Implementation
- [Interface]
- Implementation
- Operations
- Operation
- Parameter
- Operation
- Generalization2(Generable)
- [Class]
- Associations
- Class(Object)
- Interfaces
建立类图
由于JAVA语言对于上述对象图关系的描述非常难受,很多关键词之间发生重复而不得不重名,而且建立这样深层次的结构层次非常困难(从这个角度来说:JAVA很难说是一个优秀的面向对象语言)
粗线表示继承extends,细线表示组合contains,虚线表示联系associates

因为建立了大量的包来管理层次关系,导致用IDEA自带的diagram画出的图不忍直视,怎么调都不能画出期望的那样。一直是一堆点都点不开的包名:

bug修复
几乎所有的bug都出现在对于异常输出上:We expected "No, attribute mData in NetworkParam, mGrad in NetworkParam, are not hidden." but we got "No, attribute mData in Float32NetworkParam, mGrad in Float32NetworkParam, are not hidden." at line 18
在改过基本的问题后,出现了一种特殊的情况,而这种情况恰恰是指导书上几乎没有提示的部分:

在调查C3的Attribute1的Visibility时,确实是重复了,但他的父类已经犯了这个错误,应该先扔出父类的异常。
在这里,检查异常应该有一个明晰的先后关系:而且结构层次越浅,抽象层次越高的对象的异常应该最先被检查出来,抛出之后应该直接拒绝执行下一步。
(二)第二次作业
作业需求分析
本次作业,在上次作业基础上,扩展解析器,使得能够支持对UML顺序图和UML状态图的解析,并能够支持几个基本规则的验证:
对象图在第一次基础上,增加了statechartmodel collaborationmodel两个新模型,而且这两个模型几乎和之前的classmodel没有任何关系,甚至可以看做两个新工程:
- statechartmodel
- StateChartSet
- StateChart{=StateMachine}
- Region
- Transition{含有Event}
- State
- Region
- StateChart{=StateMachine}
- StateChartSet
- collaborationmodel
- Collaboration{=InteractionSet}
- Interaction
- Lifeline
- Message
- Interaction
- Collaboration{=InteractionSet}
建立类图


如图所示,建立的类图仅表示类的名称、对象关系,就已经相当复杂:30个类,分散在8个包中。结构层次一目了然,但是由于JAVA语言的局限性,仍然没有按照对象图所示建立类。
checkForUml002实现方式
如类图,checkForUml002由于只与类有关,交由ClassSet处理,依次遍历所有类MyClass,而MyClass中设有以下函数:对三种情况进行了区分,并依次添加。
public HashSet<? extends AttributeClassInformation> checkForUml002() {
HashSet<AttributeClassInformation> set = new HashSet<>();
//1. 来自重复的<属性,属性>
for (Map.Entry<String, UmlAttribute> entry :attributes.getMap().entrySet()) {
if (entry.getValue() == null) {
set.add(new AttributeClassInformation(entry.getKey(), getName()));
}
}
//2. 来自重复的<属性,对端>
for (UmlAssociationEnd end : getAssociations().getList()) {
if (attributes.contains(end.getName())) {
set.add(new AttributeClassInformation(end.getName(), getName()));
}
}
//3. 来自重复的<对端,对端>,注意null不算
HashSet<String> endSet = new HashSet<>();
for (UmlAssociationEnd end : getAssociations().getList()) {
if (end.getName() != null && endSet.contains(end.getName())) {
set.add(new AttributeClassInformation(end.getName(), getName()));
} else {
endSet.add(end.getName());
}
}
return set;
}
checkForUml008/009实现方式
这两个check是一起完成的,实现方式非常巧妙:在每个MyObject包含的Generable中设置了一个HashMap:private HashMap<UmlClassOrInterface, Boolean> map = null;
模型结束后自动将父类加到这个map中去,如果map已经含有这个父类了,将value值置为true
并且用到了深度优先递归,先添加正在查找的对象,如果它没有更新map,则等它更新完毕再继续。最后对于MyObject中的check都能一步完成:
public boolean checkForUml008() {
return getGenerable().getMap().containsKey(IdManager.getById(id));
}
public boolean checkForUml009() {
return getGenerable().getMap().containsValue(true);
}
StateChart.getSubsequentStateCount实现方式
相当于找到有向图中某个对象的所有可达点。但是最好是在模型结束时将所有点的可达点都找到。个人用的算法是对每个节点都用一次Bfs,将所有到达的节点都记录在表内。(可能有复杂度更低的算法)
private HashMap<String, HashSet<String>> map;
//<状态的name,后续状态名称集合>,null表示该状态duplicate
//如果是起始和终止态,忽略不计
private void Bfs(String name) {
HashSet<String> arrived = map.get(name);
HashSet<String> nextSet = new HashSet<>(arrived);
while (!nextSet.isEmpty()) {
String fromNode = nextSet.iterator().next();
nextSet.remove(fromNode);
if (map.get(fromNode) == null) {
continue;
}
for (String toNode : map.get(fromNode)) {
if (!arrived.contains(toNode)) {
nextSet.add(toNode);
arrived.add(toNode);
}
}
}
}
二、四个单元中架构设计及OO方法理解的演进
四个单元依次是表达式求导 多线程电梯 JML规格化 UML模型化,四次的角度各有不同,但视角逐渐变得全面,变得有层次、有深度。尤其是最后一次竟然直接以JAVA语言本身为对象进行语言上的思考与设计。
OO对我的最大影响并不是一个个具体的算法(尤其是图论中的Bfs,Floyd,Dijstra,Dfs);不是一些具体的数据结构(尤其是容器类的使用HashMap,HashSet,Arraylist,LinkList);不是一些具体的多线程交互模式(如生产者——消费者模式、工厂模式、订阅——发布者模式);不是一些具体的设计模式(如单例模式、守护者模式、观察者模式);不是一些具体的设计原则(尤其是SOLID原则:SRP,OCP,LSP,ISP,DIP);却是面向对象在哲学视角的思想与方法论。
此篇博文详细讨论了面向对象的哲学视角与方法论。
三、四个单元中测试理解与实践的演进
测试依次接触到:自动化测试、规格化测试、单元测试
自动化测试:用代码将数据管理好,并自动去运行整个程序,将数据导入并进行对比的方式。
规格化测试:针对方法而言,对每个方法都独立地写一个LLR(Low Level Request,即规格),让相应软件自动生成数据进行验证。
单元测试:针对方法而言,是一种内部的样例,直接对类进行初始化,调用相应函数,检验结果。
应用异常代价:软件都是为了某一个应用而实现的,在软件工程真正运行过程中大量的从用户端传来的数据可能会导致工程出现漏洞,有时甚至会出现极大的经济上的损失。这样的测试也是有代价的,更多时候要权衡测试的成本和应用异常代价。
个人认为,写一个单元测试时非常费力的,写了半天只检验了一个函数,而且还不能保证100%正确;写一个LLR(规格化测试)也是非常费力的,而且从LLR到实现也是吃力不讨好的过程,不如直接用自然语言描述的需求更好实现。虽然有所谓的代码覆盖率、分支覆盖率层次上的检验,其时间和空间代价对于一般的应用程序都是不可接受的。只有航天航空那种要求非常严格的软件工程才会有这样严苛的要求。
最后剩下的就是自动化测试了,可以说这个是检查代码功能正确性,已经代码效率最佳的方法。首先将所有测试样例放在同一个文件目录下,可以用python语言import OS,用命令行调用自动生成JAVA可运行程序,依次再运行所有样例,与结果进行比较。这样的自动化测试就相当于评测机了。说到底,这个才是最为实用的测试方式。
四、三个具体改进建议
- 对优秀代码进行全面而有层次地解读,学习大佬的思想
- 与其他学科进行交叉解读,如面向对象在哲学视角的思考,在计算机网络层面的关联
- 作业更加贴合实际一些、具体一些,如写一些关于UI方面的,写游戏这样能提起同学兴趣,并对同学有些实际的作用
OO_Unit4_UML模型化设计的更多相关文章
- OO_Unit4 UML模型化设计总结
OO_Unit4 UML模型化设计总结 任务简介:本单元在介绍了UML中几种基本的模型图元素的基础上,通过实现课程组提供的官方接口来完成自己的UML解析器. 架构设计 本单元最终的整体架构图如下(不包 ...
- .NET领域驱动设计—实践(穿过迷雾走向光明)
阅读目录 开篇介绍 1.1示例介绍 (OnlineExamination在线考试系统介绍) 1.2分析.建模 (对真实业务进行分析.模型化) 1.2.1 用例分析 (提取系统的所有功能需求) 1.3系 ...
- .NET领域驱动设计—初尝(三:穿过迷雾走向光明)
开篇介绍 在开始这篇富有某种奇妙感觉的文章之旅时我们先短暂的讨论一下关于软件开发方法论的简要: 纵观软件开发方法论,从瀑布模型.螺旋模型.RUP(统一软件开发过程).XP(极限编程).Agile(敏捷 ...
- [转] .NET领域驱动设计—实践(穿过迷雾走向光明)
阅读目录 开篇介绍 1.1示例介绍 (OnlineExamination在线考试系统介绍) 1.2分析.建模 (对真实业务进行分析.模型化) 1.2.1 用例分析 (提取系统的所有功能需求) 1.3系 ...
- 五指CMS发布1.4版本,更多的新功能
五指cms v1.4变更: 新增内容手动分页新增百度地图新增订单管理模块新增订单地址管理增加Microsoft YaHei字体新增推广邀请模块新增私密下载,下载函数 新增百度地图新增筛选功能 修正全局 ...
- 五指CMS发布,主打高性能
近日,五指CMS正式发布.给沉静已久的国内 CMS 行业引来不少的关注.五指CMS由原PHPCMS v9的负责人王参加主导开发.我们可以看到,由于移动互联网以及大数据的崛起,个人站长市场的逐渐减少,国 ...
- 五指CMS v1.2 GBK 发布下载
五指CMS v1.2 GBK 版本下载地址: http://www.wuzhicms.com/uploadfile/wuzhicms/wuzhicms-v1.2.zip 从内测到公测,五指 ...
- 面向对象程序设计第四单元总结(UML系列)
2019面向对象程序设计第四单元总结 前言 本单元是面向对象程序设计课程的最后一个单元了,本单元是和UML模型相关,也就是说,我们需要正确理解UML模型的基础上,对构建出的UML模型进行解析,但是 ...
- BUAA_OO_2020_Unit4_总结博客
BUAA_OO_2020_Unit4_总结 2020年春季学期第十六周,OO第四单元即最终章落下帷幕,本单元是利用Java进行UML类图的解析,完成对类图.顺序图.状态图的内部查询操作与简单的规则判断 ...
随机推荐
- IgniteMe -高校网络信息安全运维挑战赛
1 int __cdecl main(int argc, const char **argv, const char **envp) 2 { 3 void *v3; // eax 4 int v4; ...
- Airtest简单上手讲解
Airtest是网易开发的手机UI界面自动化测试工具,它原本的目的是通过所见即所得,截图点击等等功能,简化手机App图形界面测试代码编写工作. 安装和使用 由于本文的目的是介绍如何使用Airtest来 ...
- [Design Pattern With Go]设计模式-工厂模式
这次介绍的设计模式是工厂模式,这是一个比较常见的创建型模式.一般情况下,工厂模式分为三种:简单工厂.工厂方法和抽象工厂,下面慢慢举例介绍下. 简单工厂 考虑一个加密程序的应用场景,一个加密程序可能提供 ...
- 最小生成树(Prim算法,Kruskal算法 )
声明:图片及内容基于https://www.bilibili.com/video/BV1yp4y1Q74o?from=articleDetail 最小生成树原理 . 普利姆(Prim)算法 原理 Pr ...
- Java高并发测试框架JCStress
前言 如果要研究高并发,一般会借助高并发工具来进行测试.JCStress(Java Concurrency Stress)它是OpenJDK中的一个高并发测试工具,它可以帮助我们研究在高并发场景下JV ...
- Java String系列
String详解, String和CharSequence区别, StringBuilder和StringBuffer的区别 (String系列之1) StringBuilder 详解 (String ...
- GoF设计模式合集
1 概述 这篇文章是对GoF23种设计模式+1种非GoF模式的合集,由笔者自己的笔记整理而来,每个模式都详细描述了步骤,角色等,以及使用Java实现的具体的例子. 2 基础 设计模式概述 UML与面向 ...
- Mybatis3源码笔记(七)Plugin
1.Mybatis3的插件其实主要是用到了责任链和动态代理两种模式相结合而生成的.下面我们看一个例子,在执行所有update操作时,执行一个小小的测试输出. @Intercepts({@Signatu ...
- Day 12_61_多线程的创建和启动(二)
多线程的创建和启动 * 在java中实现多线程的第二种方法 实现java.lang.Runnable接口,重写run()方法 * 推荐使用这种方式,因为实现接口还可以保留类的继承. package c ...
- seaweedfs分布式文件使用示例
安装seaweedfs分布式文件存储 启动一个测试集群:2 filer(8801-8802) + 3 master(9331-9333) + 3 volume(8081-8083) 下载seaweed ...