热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

第四单元和课程总结:简单的架构设计意识

一、第四单元架构设计总结第一次作业由于需要按名查找类图模型,于是建立"Class"类进行管理由于方法具有参数导致类中存在二级结构

一、第四单元架构设计总结

  • 第一次作业
    • 由于需要按名查找类图模型,于是建立"Class"类进行管理
    • 由于方法具有参数导致类中存在二级结构,于是建立"Operation"类进行管理,再将其作为Class类的成员
    • 对重名情况的处理:
      不同对象的ID不同,对象实体也不同,但Name(String)相同,这是一个相当常见的场景。
      笔者采用以下方法进行处理:
      • 建立从ID到对象的映射:   private HashMap<String, Class> idsToClass
        这样的映射是一一映射,使用普通的HashMap即可实现。
      • 建立从Name到ID的映射: private MultiHashMap<String, String> nameToIds
        这样的映射是一对多的映射,使用自建数据结构MultiHashMap实现
      • MultiHashMap的形式:    HashMap<K, HashSet<V>> multiMap;
        通过Key可以查询到一个包含Value的HashSet。这样就实现了一对多映射的方便管理。

      • 可以预见到的是,自己建立一个 HashMap<K, HashSet<V>> multiMap 是十分方便的,其使用场景非常普遍,在两次作业中具体有:
        • 维护一对多的映射(例如,通过重复的Name查询独一无二的ID,抛出DuplicateClassNameException等)
        • 维护简单图的邻接表结构(一个点的邻接点或关联边构成一个集合)

    • 由于输入的元素类型顺序不定,于是构造UmlComparator类实现Comparator接口,用于对元素进行排序,
      要求任意元素的父元素出现顺序在其之前: Arrays.sort(elements, new UmlComparator()); 
    • 具体架构大意如下类图:


  • 第二次作业:
    • 继承了第一次作业的类图解析与处理架构
    • 由于需要按名查找状态机模型,于是建立"StateMachine"类进行管理
    • 由于要求撰写类实现General接口,但是类不支持多继承,所以为了实现类图维护与有效性检查、顺序图维护、状态图维护这三个完全独立的功能
      将三个独立的功能分散到三个不同的类中,再将它们组合到最终的目标类中(将他们实例化,作为成员)。构造时将元素同时传给三个类进行构造即可。
      这样,最终要求的目标类就仅剩对三个类中方法的调用,十分简洁,且三个功能互不干扰。
      同时,对源码结构的管理也变得十分简洁,如下图所示:
    • 具体架构大意如下类间关系图:

 

二、课程中对架构设计及OO理解的演进

  • 第一单元
    • 应当具有好的可拓展性,不应在方法中做出太多基于当前假设的妥协
    • 应当将方法分解为基本原子操作的组合,让方法各司其职,而不是出现:
      • 方法间的功能重合
      • 迭代时的方法内容手动拆分
      • 方法的副作用大,内容包含与其名称不符的额外操作
      • 某方法中接了本来应该在上层方法中进行逻辑判断的锅
    • 准确识别继承和接口的使用时机
      • 当且仅当确实有可抽象的共性内容和提取的必要时,才进行继承和接口操作
      • 善用工厂模式系列和单例模式
      • 在最初设计时留出进行可拓展的空间,该空间很大程度由类间关系的设计决定
    • 架构设计应当给性能的优化留出空间,如将需要算法的操作放在某个方法中,并将其尽量与其他方法解耦,便于后续进行调整
      • 典型例子:给定图,求最短路、联通块等
      • 不应进行重复性的工作,应借助程序员理清逻辑和过程、finished标记、lazy等方法提高性能
  • 第二单元
    • 在多线程程序中,应当将同步执行区域的代码和直接调用的代码区分开,放进不同的类中(如:调度器被电梯线程直接调用代码,没有必要设置成一个线程
    • 尽量少使用线程,准确识别什么对象应该单独承载一个线程(如:每部电梯一个线程,还是每个请求一个线程)
    • 可以在设计时和编码中使用UML顺序图对每个线程间的交互和线程的进展进行设计
  • 第三单元和第四单元
    • 尽量识别出可抽象的、共有的功能或数据结构,单独建立一个类进行管理,并进行有效复用,如:
      • 第四单元的MultiHashMap类,既能维护图结构,又能完成一对多的映射,做到了高效的复用
      • 第三单元的ShortestPath类和Connectivity类,配合Graph类分别进行运算,在主类看来就成为了一个完成特定功能而无需关心的工具黑箱
    • 完全无关的功能,应该由完全独立的类(甚至是package)实现,再在主逻辑类中进行组合,尽量将核心功能下放
    • UML图是一种辅助设计的好的工具,不仅仅是类图,其顺序图和状态图对于程序员也十分重要
      • 状态图在设计和编码过程中是极其重要的逻辑指导
      • 顺序图在多线程程序设计中具有十分重要的意义

三、课程中对测试的理解与实践的演进

  • 第一单元:对于简单的输入-输出型程序:
    • 具有固定格式的:使用数据生成器进行批量数据生成和测试
    • 具有大量分支的:首先总结出每个分支处的组合情况,然后在数据生成器和手造数据中确保覆盖每种情况
    • 首先使用数据生成器等技巧覆盖大部分的情况,然后针对其求补集,人工构造小规模但刁钻的数据进行进一步的确保
  • 第二单元:对于交互输入和多线程程序
    • 使用定时投喂模拟器,在关键的时间节点(如上一条请求刚刚处理完、刚刚开始处理等)附近投喂交互性的输入数据进行测试
    • 构造数据规模不大但对同步互斥性、线程协作要求高的数据,进行反复多次测试,尽量降低不可复现bug的可能性
  • 第三单元:
    • 使用JUnit对每个类的每个方法进行单元测试,首先尽量保证每个方法内部的正确性
    • 使用简单的类似JML的语言(自然语言和Java相结合的方式笔者觉得较好)对方法、类和数据进行规范
    • 在JUnit的过程中,根据上述的规范语言构造针对性的测试用例

四、课程收获

  •  Java程序设计
    • 基础语言
      • 大数、可变长参数等特性
      • lambda、泛型编程等奇技淫巧
      • HashMap、HashSet等各种各样好用的Collection
    • 高级
      • Junit与单元测试
      • 并发、多线程编程
  • 面向对象设计
    • 继承与接口的类间关系设计
    • 好的设计模式及其应用场景
    • 第一次进行系统的面向对象程序实践
    • 不断丰富需求下的程序重构与迭代
    • UML类图、协作图、状态图的应用
  • Generally程序设计

    • 契约式程序设计与JML类似物
    • 单元测试

五、关于课程的三个具体建议

  1. 放弃对JML的强制语法要求和基于JML自动生成JUnit测试,但保留前置条件、后置条件等说明
    即,不要求求出绝对正确的JML语言,也不要求使用OpenJML等工具对程序进行验证和测试。(由于其工具链并不完善)
    但,保留PRE-condition、POST-condition等的撰写和阅读要求,它们是十分重要的。
    表意明确是最重要的,是不是精确使用JML并不是那么重要。即使是自然语言+Java的组合,只要能达到目的也一样好。
    不应该为了形式而忘了其最初的目的。

  2. 第三单元和第四单元的讲授重点是JML和UML,作业的考察重点却是类似于第一单元的简单面向对象程序设计,作业意义不大
    可以将某一单元的内容改为复杂的面向对象设计,如应用复杂的设计模式等。
    在第一单元中,课程组鼓励大家使用更为先进的设计模式,但没有硬性要求。
    在后续的单元中,应该对其加大训练力度,否则其训练强度不够,难以过渡到实际开发中的复杂场景要求。

  3. 实验课的进一步科学化。
    目前的实验课有如下几个问题:
    (1)    题面的说明不够精确、严谨。(如多线程的某次实验,代码中和题面中提到的输出内容完全不符,严重影响自动测评的正确性)
    (2)    评分标准模糊,评分手段不够严谨。(如许多代码题却无法进行有效的自动测评,只能由人工测试。如JML的补充等。)
    (3)    上午讲完下午考,不够熟悉。

感谢课程组的努力,祝BUAA OO课程越来越好!


推荐阅读
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 基于事件驱动的并发编程及其消息通信机制的同步与异步、阻塞与非阻塞、IO模型的分类
    本文介绍了基于事件驱动的并发编程中的消息通信机制,包括同步和异步的概念及其区别,阻塞和非阻塞的状态,以及IO模型的分类。同步阻塞IO、同步非阻塞IO、异步阻塞IO和异步非阻塞IO等不同的IO模型被详细解释。这些概念和模型对于理解并发编程中的消息通信和IO操作具有重要意义。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • JVM 学习总结(三)——对象存活判定算法的两种实现
    本文介绍了垃圾收集器在回收堆内存前确定对象存活的两种算法:引用计数算法和可达性分析算法。引用计数算法通过计数器判定对象是否存活,虽然简单高效,但无法解决循环引用的问题;可达性分析算法通过判断对象是否可达来确定存活对象,是主流的Java虚拟机内存管理算法。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 本文介绍了一个适用于PHP应用快速接入TRX和TRC20数字资产的开发包,该开发包支持使用自有Tron区块链节点的应用场景,也支持基于Tron官方公共API服务的轻量级部署场景。提供的功能包括生成地址、验证地址、查询余额、交易转账、查询最新区块和查询交易信息等。详细信息可参考tron-php的Github地址:https://github.com/Fenguoz/tron-php。 ... [详细]
  • 开发笔记:Java是如何读取和写入浏览器Cookies的
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Java是如何读取和写入浏览器Cookies的相关的知识,希望对你有一定的参考价值。首先我 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有