CSDN博客传送门

@

一、架构设计

(一)第一次作业

本次作业关于UML中的类图。如果说JAVA是用来描述对象及其联系的一种建模语言,那么UML则是用来描述JAVA语言的高层次建模语言,而我们需要完成的作业则是对UML语言的描述及对UML对象的管理。随着层次(此处“层次”并非抽象层次,而是结构层次,高层和底层之间具有组合关系)逐渐地提高,思想的复杂度和抽象性也成倍地提高(需要在多个不同层次去思考问题)。

作业需求分析

  • 通过实现UmlInteraction这个官方提供的接口,来实现自己的UmlInteraction解析器。

由于对象之间的关系无非内涵(组合)、外延(继承)、耦合(联系):

  • 用缩进表示结构层次(组合关系)
  • 用括号()表示抽象层次(继承关系)
  • []表示指向对象的指针(联系关系):其中必然联系同时是对象中的组合(需要用缩进表示),偶然联系则直接写在对象后面

用对象图来表示这三种关系如下:

  • ClassModel

    • Interfaces

      • Interface(Object)

        • Associations

          • Association

            • [Object]
        • Generalizations(Generable)
          • Generalization1(Generable)

            • [Interface]
        • Implementations
          • Implementation

            • [Interface]
        • Operations
          • Operation
    • Classes
      • Class(Object)

        • Associations

          • Association

            • [Object]
        • Attributes
          • Attribute
        • Implementations
          • Implementation

            • [Interface]
        • Operations
          • Operation

            • Parameter
        • Generalization2(Generable)
          • [Class]

建立类图

由于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
  • collaborationmodel
    • Collaboration{=InteractionSet}

      • Interaction

        • Lifeline
        • Message

建立类图





如图所示,建立的类图仅表示类的名称、对象关系,就已经相当复杂: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可运行程序,依次再运行所有样例,与结果进行比较。这样的自动化测试就相当于评测机了。说到底,这个才是最为实用的测试方式。

四、三个具体改进建议

  1. 对优秀代码进行全面而有层次地解读,学习大佬的思想
  2. 与其他学科进行交叉解读,如面向对象在哲学视角的思考,在计算机网络层面的关联
  3. 作业更加贴合实际一些、具体一些,如写一些关于UI方面的,写游戏这样能提起同学兴趣,并对同学有些实际的作用

OO_Unit4_UML模型化设计的更多相关文章

  1. OO_Unit4 UML模型化设计总结

    OO_Unit4 UML模型化设计总结 任务简介:本单元在介绍了UML中几种基本的模型图元素的基础上,通过实现课程组提供的官方接口来完成自己的UML解析器. 架构设计 本单元最终的整体架构图如下(不包 ...

  2. .NET领域驱动设计—实践(穿过迷雾走向光明)

    阅读目录 开篇介绍 1.1示例介绍 (OnlineExamination在线考试系统介绍) 1.2分析.建模 (对真实业务进行分析.模型化) 1.2.1 用例分析 (提取系统的所有功能需求) 1.3系 ...

  3. .NET领域驱动设计—初尝(三:穿过迷雾走向光明)

    开篇介绍 在开始这篇富有某种奇妙感觉的文章之旅时我们先短暂的讨论一下关于软件开发方法论的简要: 纵观软件开发方法论,从瀑布模型.螺旋模型.RUP(统一软件开发过程).XP(极限编程).Agile(敏捷 ...

  4. [转] .NET领域驱动设计—实践(穿过迷雾走向光明)

    阅读目录 开篇介绍 1.1示例介绍 (OnlineExamination在线考试系统介绍) 1.2分析.建模 (对真实业务进行分析.模型化) 1.2.1 用例分析 (提取系统的所有功能需求) 1.3系 ...

  5. 五指CMS发布1.4版本,更多的新功能

    五指cms v1.4变更: 新增内容手动分页新增百度地图新增订单管理模块新增订单地址管理增加Microsoft YaHei字体新增推广邀请模块新增私密下载,下载函数 新增百度地图新增筛选功能 修正全局 ...

  6. 五指CMS发布,主打高性能

    近日,五指CMS正式发布.给沉静已久的国内 CMS 行业引来不少的关注.五指CMS由原PHPCMS v9的负责人王参加主导开发.我们可以看到,由于移动互联网以及大数据的崛起,个人站长市场的逐渐减少,国 ...

  7. 五指CMS v1.2 GBK 发布下载

    五指CMS v1.2 GBK 版本下载地址: http://www.wuzhicms.com/uploadfile/wuzhicms/wuzhicms-v1.2.zip       从内测到公测,五指 ...

  8. 面向对象程序设计第四单元总结(UML系列)

    2019面向对象程序设计第四单元总结 前言 ​ 本单元是面向对象程序设计课程的最后一个单元了,本单元是和UML模型相关,也就是说,我们需要正确理解UML模型的基础上,对构建出的UML模型进行解析,但是 ...

  9. BUAA_OO_2020_Unit4_总结博客

    BUAA_OO_2020_Unit4_总结 2020年春季学期第十六周,OO第四单元即最终章落下帷幕,本单元是利用Java进行UML类图的解析,完成对类图.顺序图.状态图的内部查询操作与简单的规则判断 ...

随机推荐

  1. Scientific Internet Access

    下载小飞机 https://github.com/shadowsocksr-backup 寻找ssr https://github.com/Alvin9999/new-pac/wiki/ss%E5%8 ...

  2. Mybatis日志源码探究

    一.项目搭建 1.pom.xml <dependencies> <dependency> <groupId>log4j</groupId> <ar ...

  3. 设计模式——从工厂方法模式到 IOC/DI思想

    回顾简单工厂 回顾:从接口的角度去理解简单工厂模式 前面说到了简单工厂的本质是选择实现,说白了是由一个专门的类去负责生产我们所需要的对象,从而将对象的创建从代码中剥离出来,实现松耦合.我们来看一个例子 ...

  4. [游记]2020/CSP - S总结

    2020 / C S P − S 总 结 2020/CSP - S总结 2020/CSP−S总结 这年的 C S P CSP CSP考的不是很理想,本来稳进的 C S P − J CSP-J CSP− ...

  5. [DP]城市交通

    城市交通 Time Limit:1000MS--Memory Limit:65536K 题目描述 有n个城市,编号1~n,有些城市之间有路相连,有些则没有,有路则当然有一个距离.现在规定只能从编号小的 ...

  6. Cloudreve 自建云盘实践,我说了没人能限得了我的容量和速度!

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 为啥要用自建网盘,市面上的云盘不香了? 每一个用户需求的背后都是因为有场景存在,而这 ...

  7. JS基础学习第二天

    类型转换 类型转换就是指将其他的数据类型,转换为String Number 或 Boolean 转换为String 方式一(强制类型转换): 调用被转换数据的toString()方法例子:var a ...

  8. Python基础(十八):面向对象“类”第一课

    记住:编写函数就是"面向过程",编写类就是"面向对象".类也是很多同学的一大学习难点,因此我这里还是准备带着大家学习一下. 类和对象对比 对象 : 具有行为和属 ...

  9. 面试关于Spring循环依赖问题,我建议你这么答!

    写在前面 在关于Spring的面试中,我们经常会被问到一个问题:Spring是如何解决循环依赖的问题的. 这个问题算是关于Spring的一个高频面试题,因为如果不刻意研读,相信即使读过源码,面试者也不 ...

  10. Dynamics CRM使用Web Api时如果参数里面包含"&"的时候的处理方法

    当我们使用Dynamics CRM的Api的时候如果遇到查询字段的参数里面有&符号的话会影响Api的取值直接报错.原因是因为&符号在Url上面是一个关键字,这个关键字可以截断Url表示 ...