HIT 软件构造 lab3

2020年春季学期
计算机学院《软件构造》课程

Lab 3实验报告

姓名 赵旭东
学号 1180300223
班号 1803002
电子邮件 [email protected]

手机号码 13199515179

目录

1 实验目标概述 1
2 实验环境配置 1
3 实验过程 1
3.1 待开发的三个应用场景 2
3.2 面向可复用性和可维护性的设计:PlanningEntry 2
3.2.1 PlanningEntry的共性操作 2
3.2.2 局部共性特征的设计方案 3
3.2.3 面向各应用的PlanningEntry子类型设计(个性化特征的设计方案) 3
3.3 面向复用的设计:R 8
3.4 面向复用的设计:Location 10
3.5 面向复用的设计:Timeslot 10
3.6 面向复用的设计:EntryState及State设计模式 11
3.7 面向应用的设计:Board 12
3.8 Board的可视化:外部API的复用 14
3.9 可复用API设计及Façade设计模式 14
3.9.1 检测一组计划项之间是否存在位置独占冲突 14
3.9.2 检测一组计划项之间是否存在资源独占冲突 15
3.9.3 提取面向特定资源的前序计划项 15
3.10 资源并没有设计模式应用 15
3.10.1 Factory Method 15
3.10.2 Iterator 16
3.10.3 Strategy 17
3.11 应用设计与开发 18
3.11.1 航班应用 18
3.11.2 高铁应用 23
3.11.3 课表应用 25
3.12 基于语法的数据读入 27
3.13 应对面临的新变化 28
3.13.1 变化1 28
3.13.2 变化2 29
3.13.3 变化3 30
3.14 Git仓库结构 31
4 实验进度记录 32
5 实验过程中遇到的困难与解决途径 32
6 实验过程中收获的经验、教训、感想 33
6.1 实验过程中收获的经验和教训 33
6.2 针对以下方面的感受 33

1 实验目标概述
本次实验覆盖课程第 3、4、5 章的内容,目标是编写具有可复用性和可维护
性的软件,主要使用以下软件构造技术:
⚫ 子类型、泛型、多态、重写、重载
⚫ 继承、代理、组合
⚫ 常见的 OO 设计模式
⚫ 语法驱动的编程、正则表达式
⚫ 基于状态的编程
⚫ API 设计、API 复用
本次实验给定了五个具体应用(高铁车次管理、航班管理、操作系统进程管
理、大学课表管理、学习活动日程管理),学生不是直接针对五个应用分别编程
实现,而是通过 ADT 和泛型等抽象技术,开发一套可复用的 ADT 及其实现,充分考虑这些应用之间的相似性和差异性,使 ADT 有更大程度的复用(可复用性)和更容易面向各种变化(可维护性)。
2 实验环境配置
简要陈述你配置本次实验所需环境的过程,必要时可以给出屏幕截图。
特别是要记录配置过程中遇到的问题和困难,以及如何解决的。
Eclipse, Git, IDEA
在这里给出你的GitHub Lab3仓库的URL地址(Lab3-学号)。
https://github.com/ComputerScienceHIT/Lab3-1180300223.git
3 实验过程
请仔细对照实验手册,针对每一项任务,在下面各节中记录你的实验过程、阐述你的设计思路和问题求解思路,可辅之以示意图或关键源代码加以说明(但千万不要把你的源代码全部粘贴过来!)。
3.1 待开发的三个应用场景
列出你所选定的三个应用。
分析三个应用场景的异同,理解需求:它们在哪些方面有共性、哪些方面有差异。
我选择的应用是:

  1. 航班管理
  2. 高铁车次管理
  3. 大学课表管理

共性:

  1. 创建一个新的计划项,并且都具有一个专属的label(例如航班的航班号, 高铁的车次号, 课程的名称等)
  2. 计划项可以取消, 分配资源, 启动, 完成
  3. 可以获得计划项的label
  4. 可以获得计划项的当前状态
  5. 可以获得计划项的位置(从一个由Location类构成的list中获得)
  6. 可以设置一个由Timeslot类构成的list, 并且也能得到时间对(从一个由Timeslot类构成的list中获得)中的起始和终止时间

差异:

  1. 三种计划项的位置数量不相同
  2. CourseEntry可以在开始前修改位置
  3. TrainEntry可以中停(block)

3.2 面向可复用性和可维护性的设计:PlanningEntry
该节是本实验的核心部分。
3.2.1 PlanningEntry的共性操作
共性:

  1. 创建一个新的计划项,并且都具有一个专属的label(例如航班的航班号, 高铁的车次号, 课程的名称等)
  2. 计划项可以取消, 分配资源, 启动, 完成
  3. 可以获得计划项的label
  4. 可以获得计划项的当前状态和资源
  5. 可以获得计划项的位置(从一个由Location类构成的list中获得)
  6. 可以设置一个由Timeslot类构成的list, 并且也能得到时间对(从一个由Timeslot类构成的list中获得)中的起始和终止时间

3.2.2 局部共性特征的设计方案
通过对三种计划项进行抽象之后, 我认为我所选择的三种计划项就有上面所说的几种共性操作,接下来就一项一项地进行抽象

  1. 创建一个新的计划项
    我认为一个计划项必需的参数为其label, 位置以及时间对. 但是由于位置设置各个计划项并不相同,那么就需要将其拆开, 所以我设置的创建计划项就是将计划项的label设置, 并将计划项的状态更改为”WAITING”
  2. 计划项的取消, 分配资源, 启动, 结束这几个操作之间是有关联的, 但是为了之后APP中给用户反馈更加明显, 我在这里并没有考虑状态转换与状态本身的联系, 而是在之后的APP中进行判断
  3. 获得label, 状态, 资源很简单,就是一个Getter方法, lable和状态是不可变量, 不需要做其他调整; 为了防止resource泄露而被外部篡改, 我选择new一个新的resource使其与计划项resource相同, 返回这个新的resource
  4. 考虑到可扩展性, 我决定将计划项中的Location设置为一个list, 这样方便以后如果要增加位置的数量等一系列的扩展
  5. 时间对与Location差不多, 也是为了其扩展性.
    HIT 软件构造 lab3
    图表 1 CommonPlanningEntry的注释

3.2.3 面向各应用的PlanningEntry子类型设计(个性化特征的设计方案)
差异:

  1. 三种计划项的位置数量不相同
  2. CourseEntry可以在开始前修改位置
  3. TrainEntry可以中停(block)

由上面几种差异我们可以轻松地个性化特征:

  1. FlightEntry
    航班计划项的个性化特征就是有两个位置, 其他的不多, 只需要一个TwoLocaitonEntry的接口就行
    HIT 软件构造 lab3
    图表 2 TwoLocaitonEntry接口

  2. TrainEntry
    高铁计划项的个性化特征有两个, 一个是多位置(≥2), 一个是可阻塞重启, 所以需要MultipleLocationEntry接口和BlockableEntry接口
    HIT 软件构造 lab3
    图表 3 MultipleLocationEntry接口
    由于我设计的ADT无法直接获得locations的list, 所以不得不做出妥协来获得这个list的size.
    HIT 软件构造 lab3
    图表 4 BlockableEntry接口

  3. CourseEntry
    课程计划项虽然有两个个性化特征, 但是考虑到另一个单位置的计划项也能更改位置, 不妨将两个特征写进同一个接口中, 即单位置以及位置可更改, 需要SingleLocationEntry接口
    HIT 软件构造 lab3
    图表 5 SingleLocationEntry接口
    在实现个性化特征的方法中, 我选择了方法4:定义接口并实现具体类,通过继承树实现各应用在多维度上的不同特征取值的组合
    选择方法4的原因是本人能力有限, 认为方法4的方法简单容易理解, 但是我在后面的设计我个人认为还算满意(除了GUI), 基本上修改工作量极小,个人认为维护起来的成本并不算太高
    HIT 软件构造 lab3
    图表 6 TwoLocationEntryImpl

HIT 软件构造 lab3
图表 7 MultipleLocationEntryImpl

HIT 软件构造 lab3
图表 8 MultipleLocationAndBlockableEntryImpl
HIT 软件构造 lab3

图表 9 SingleLocationEntryImpl
通过以上组合最终完成了各个部分的个性化, 只需要将各个计划项类继承以上其个性化部分的类即可

测试策略基本都相同,就是根据自己写的规约来进行测试,测试每一个方法的正确性即可,后续不再重复,这里提供所有测试的覆盖度,个人认为在可接受范围之内
3.3 面向复用的设计:R

  1. Plane
    飞机作为航班计划项的资源, 在实验手册中规定了其必须具有飞机编号、机型号(A350、B787、C919 等)、座位数、机龄(例如 2.5 年)
    方法只需要Getter即可
    HIT 软件构造 lab3
    图表 10 Plane类的注释

  2. Carriage
    高铁车厢作为高铁计划项的资源, 在实验手册中规定了其必须有车厢唯一编号、类型(商务、一等、二等、软卧、硬卧、硬座、行李车、餐车)、定员数(例如 100 人)、出厂年份
    方法同样只需要Getter即可
    HIT 软件构造 lab3
    图表 11 Carriage类的注释
    但需要注意的是, 我的type使用了enum枚举类, 列出了所有车厢的类型
    HIT 软件构造 lab3
    图表 12 枚举类的车厢类型

  3. Teacher
    Teacher作为课程计划项的资源, 在实验手册中规定了其必须有身份证号、姓名、性别、职称
    方法同样只需要Getter即可
    HIT 软件构造 lab3
    图表 13 Teacher类的注释

3.4 面向复用的设计:Location
Location作为整个实验中非常重要的部分, 在实验手册中规定了其必须有经度、纬度、名称、是否可共享使用
方法只需要Getter即可, 同时重载了equals方法
其中的是否可共享由于受到计划项的影响, 所以其设定的时候应该根据相应的计划项来设置, 不应该让用户来决定位置的共享性
HIT 软件构造 lab3
图表 14 Location类的注释
3.5 面向复用的设计:Timeslot
Timeslot同样作为整个实验中非常重要的部分, 在实验手册中设定为一个起对, 要求的格式为yyyy-MM-dd HH:mm, 但是在最后APP的测试过程中, 如果中间输入空格会导致输入格式错误, 所以我将格式改为了yyyy-MM-dd&HH:mm
方法只需要Getter即可
HIT 软件构造 lab3
图表 15 Timeslot类的注释

3.6 面向复用的设计:EntryState及State设计模式
EntryState在实验手册中列出了所有的可能状态,分别是Waiting,Allocated,Canceled,Running,Blocked,Ended总共6种状态
使用State设计模式,首先定义一个State接口,方法为getState
之后将ConcreteState设计出来,就是以上所说的6种状态,它们需要implements State接口,实现方法getString,具体的实现方法就是返回该状态对应的状态字符串
最后构造Context类,Context类的作用时用来定义当前状态的,在本实验中我并没有在State设计模式中添加除了改变状态以外的操作
HIT 软件构造 lab3
图表 16 Context类
3.7 面向应用的设计:Board

  1. FlightEntryBoard
    我在FlightBoard中设置了两个由FlightEntry构成的list,一个用来存储以选定位置为出发点的计划项,一个用来存储以选定位置为到达点的计划项,构造Board的时候需要输入两个list,在App中由用户输入选定的Locaiton,通过将指定的计划项加入list最后打印,同时实现了public void visualize()方法
    HIT 软件构造 lab3
    图表 17 FlightEntryBoard类的注释

  2. TrainEntryBoard
    TrainEntryBoard与FlightEntryBoard基本相同,不过多介绍
    HIT 软件构造 lab3
    图表 18 TrainEntryBoard的注释

  3. CourseEntryBoard
    CourseBoard由于只有一个位置,所以只需要一个list即可,其他的与另外两个Board类相同
    HIT 软件构造 lab3
    图表 19 CourseEntryBoard的注释
    3.8 Board的可视化:外部API的复用
    由于我在一开始的学习方向出了偏差以及个人能力实在有限,GUI使用了JTextPane,最终的效果不是很让人满意
    需要说明的是,我使用了Eclipse中的插件WindowsBuilder进行Borad类的GUI实现,该插件免去了框架和大部分繁琐的代码,使用起来十分简洁方便
    HIT 软件构造 lab3
    图表 20 GUI的效果图(图中数据仅为效果演示,并非真实数据)
    3.9 可复用API设计及Façade设计模式
    前两个API最重要的部分就是检测是否存在时间重叠,所以我写了一个方法timeOverlap(List<PlanningEntry> entries)来检测一组计划项中是否存在时间重叠的情况,如果存在时间重叠才会进行位置和资源是否冲突的判断
    3.9.1 检测一组计划项之间是否存在位置独占冲突
    在实验手册中给出了位置冲突的定义:如果两个计划项在同一时间点上占用了不可共享的位置,那么就存在了位置冲突
    位置冲突首先需要的是计划项的位置具有不可共享属性,这个是最基本的要求,可以共享的计划项位置是不会发生位置独占冲突的
    满足了计划项的位置具有不可共享属性之后,位置独占冲突还必须存在时间重叠,同时还需要计划项之间的位置相同,如果存在时间重叠且位置相同就会发生位置冲突
    3.9.2 检测一组计划项之间是否存在资源独占冲突
    在实验手册中给出了资源的定义:如果两个计划项在同一时间点上占用了同样的资源,那么就存在了资源冲突
    资源并没有可共享性,所以资源独占冲突需要存在时间重叠,同时还需要计划项之间使用的资源相同,如果存在时间重叠且位置使用的资源就会发生位置冲突
    3.9.3 提取面向特定资源的前序计划项
    在实验手册中给出了这个方法的定义:针对某个资源 r 和使用 r 的某个计划项 e,从一组计划项中找出 e 的前序 f,f 也使用资源 r,f 的执行时间在 e 之前,且在 e 和 f 之间不存在使用资源 r 的其他计划项。若不存在这样的计划项f,则返回 null。如果存在多个这样的 f,返回其中任意一个即可。
    我选择的三个计划项都是可区分个体的,该方法的意思就是指定一个计划项,找出在这个计划项执行时间之前的计划项,这个部分需要借鉴部分我前面所说的检测时间重叠的思想
    3.10 资源并没有设计模式应用
    请分小节介绍每种设计模式在你的ADT和应用设计中的具体应用。
    3.10.1 Factory Method

  4. 设计
    我的工厂方法首先定义了一个抽象类Factory,里面定义了一个抽象方法Manufacture,作用是利用工厂创建新的计划项
    又定义了一个PlanningEntryProduct,作用是新建一个计划项对象
    ConcreteEntryProduct是三种计划项的具体化,为了方便新建计划项,我设置了一个list,之后每次新建只需要调用CreateEntry函数就行,不需要新建计划项也不用新建工厂对象
    之后就是三个计划项的具体工厂,新加了一个getEntry功能

  5. 应用
    工厂方法的应用主要体现在App中, 例如FlightScheduleApp中, 我只初始化过一次工厂, 之后所有的创建都是由工厂的方法创建的, 这样不仅提高了效率, 还降低了数据泄露的风险
    HIT 软件构造 lab3
    图表 21 在App中新建工厂
    HIT 软件构造 lab3
    图表 22 利用工厂方法新建计划项
    3.10.2 Iterator

  6. 设计
    我的迭代器仿照ArrayList中的迭代器来写的, 由于CourseBoard里只有一个list, 用来举例比较方便, 不妨用CourseEntry来举例
    HIT 软件构造 lab3
    图表 23 CourseBoard里的迭代器

  7. 应用
    对于迭代器的使用,我的使用方式是通过迭代器按照时间从早到晚的次序遍历其中包含的所有计划项,方便后面的显示。
    HIT 软件构造 lab3
    图表 24 迭代器的使用
    3.10.3 Strategy

  8. 设计
    我的策略模式选择了之前3.10中的checkResourceExclusiveConflict API, 我的两种方法大体类似, 不同的地方是其循环方式不同
    HIT 软件构造 lab3
    图表 25 方法1的循环方式
    HIT 软件构造 lab3
    图表 26 方法2的循环方式

  9. 应用
    对于策略模式的应用, 选用的方法由用户决定
    HIT 软件构造 lab3
    图表 27 策略模式的应用
    3.11 应用设计与开发
    利用上述设计和实现的ADT,实现手册里要求的各项功能。
    只需保留你选定的三个应用即可。
    3.11.1 航班应用
    航班应用的功能如下张截图中的Menu所示
    HIT 软件构造 lab3
    图表 28 航班应用的功能
    航班应用的功能我是在控制台中一一实现的, 使用了switch-case结构
    在控制台输入1后会提示用户删除或增加可用资源
    HIT 软件构造 lab3
    图表 29 选择1
    增加资源会提示用户依次输入必要信息
    HIT 软件构造 lab3
    图表 30 增加资源
    在控制台输入2后会提示用户删除或增加可用位置
    HIT 软件构造 lab3
    图表 31 选择2
    增加位置会提示用户依次输入必要信息
    HIT 软件构造 lab3
    图表 32 增加可用位置
    在控制台输入3后会提示用户增加新的计划项, 并输入相关内容
    HIT 软件构造 lab3
    图表 33 选择3
    在控制台输入4后会提示用户取消一个计划项
    HIT 软件构造 lab3
    图表 34 选择4
    在控制台输入5后会提示用户分配资源给一个计划项, 但是被取消的计划项无法分配资源
    HIT 软件构造 lab3
    图表 35 选择5(无法分配资源)
    HIT 软件构造 lab3
    图表 36 选择5(正常分配资源)
    在控制台输入6后会提示用户启动一个计划项
    HIT 软件构造 lab3
    图表 37 选择6
    在控制台输入7后会提示用户结束一个计划项
    HIT 软件构造 lab3
    图表 38 选择7
    在控制台输入8后会提示用户选择一个计划项并获得其状态
    HIT 软件构造 lab3
    图表 39 选择8
    在控制台输入9后会展示给用户是否存在资源冲突
    HIT 软件构造 lab3
    图表 40 选择9,策略1
    HIT 软件构造 lab3
    图表 41 选择9,策略2
    在控制台输入10后会提示用户选择资源和计划项,并展示前序计划项的label
    HIT 软件构造 lab3
    图表 42 选择10(存在前序计划项的情况)
    HIT 软件构造 lab3
    图表 43 选择10(不存在前序计划项的情况)
    在控制台输入11后会展示给用户显示板(未分配资源的计划项不会出现)
    HIT 软件构造 lab3
    图表 44选择11
    在控制台输入12后结束App,右上方停止按钮变灰
    HIT 软件构造 lab3
    图表 45 选择12,退出程序
    3.11.2 高铁应用
    高铁应用的功能如下张截图中的Menu所示
    HIT 软件构造 lab3
    图表 46 高铁应用功能
    高铁应用的很多功能都与航班应用差不多,所以接下来只展示与航班应用不同的功能部分
    在控制台输入1后会提示用户删除或增加可用资源,与航班应用不同的是会提示用户输入车厢数量以及车厢类型
    HIT 软件构造 lab3
    图表 47 选择1
    在控制台输入3后会提示用户增加新的计划项, 并输入相关内容,与航班应用不同的是会提示用户输入高铁一共有多少站
    HIT 软件构造 lab3
    图表 48 选择3
    在控制台输入7后会提示用户选择一个计划项并阻塞
    HIT 软件构造 lab3
    图表 49 选择7
    HIT 软件构造 lab3
    图表 50 此时的状态
    在控制台输入8后会提示用户选择一个计划项并重启
    HIT 软件构造 lab3
    图表 51选择8
    航班应用和高铁应用的GUI基本相同,在前面展示过,就不在此处展示了
    3.11.3 课表应用
    课表应用的功能如下张截图中的Menu所示
    HIT 软件构造 lab3
    图表 52 课表应用功能
    在控制台输入1后会提示用户删除或增加可用资源,会提示用户输入与老师相关的信息
    HIT 软件构造 lab3
    图表 53 选择1
    在控制台输入3后会提示用户增加新的计划项, 并输入相关内容
    HIT 软件构造 lab3
    图表 54 选择3
    在控制台输入11后会告知用户是否存在位置冲突,之前我添加了两个课程,时间分别是(2020-05-15 10:00,2020-05-15 12:00)和(2020-05-15 10:10,2020-05-15 11:45),位置均为正心101,所以存在位置冲突
    HIT 软件构造 lab3
    图表 55 选择11
    在控制台输入7后会提示用户更改位置,由于算法设计课还未开始,可以更改位置
    HIT 软件构造 lab3
    图表 56 选择7,更改位置
    此时在控制台输入11后,显示已经没有了位置冲突
    HIT 软件构造 lab3
    图表 57 此时没有位置冲突
    此时在控制台输入13后,显示GUI
    HIT 软件构造 lab3
    图表 58 GUI显示
    3.12 基于语法的数据读入
    该方法再实验手册中有详细说明:从一个外部文本文
    件读入数据并使用正则表达式 parser 对其进行解析,从中抽取一组航班息,构造一组航班计划项实体集合。
    根据手册中给出的既定模板

    可以通过编写对应的正则表达式来进行读取
    读取文件的方式是通过BufferedReader来读取
    3.13 应对面临的新变化
    只考虑你选定的三个应用的变化即可。
    3.13.1 变化1
    评估之前的设计是否可应对变化、代价如何
    如何修改设计以应对变化
    变化1:航班支持经停,即包含最多 1 个中间经停机场,例如哈尔滨-威海-深圳
    是否可应对变化:可以
    代价:更改计划项继承的父类,增加App中的功能,个人认为代价较小
    修改方案:
    将FlightEntry继承的父类修改,从TwoLocationEntryImpl修改为:MultipleLocationAndBlockableEntryImpl类,并在App中增加相应功能即可
    HIT 软件构造 lab3
    图表 59 修改后的App
    HIT 软件构造 lab3
    图表 60 成功阻塞计划项
    3.13.2 变化2
    评估之前的设计是否可应对变化、代价如何
    如何修改设计以应对变化
    变化2:如果高铁车次已经分配了车厢资源,则不能被取消
    是否可应对变化:可以
    代价:修改App中的状态更改逻辑,代价极小
    修改方案:
    将TrainScheduleApp中的取消计划项的逻辑更改为状态为分配好资源后不可取消即可
    HIT 软件构造 lab3
    图表 61为计划项分配资源
    HIT 软件构造 lab3
    图表 62 分配资源后不可被取消
    3.13.3 变化3
    评估之前的设计是否可应对变化、代价如何
    如何修改设计以应对变化
    变化3:课程可以有多个教师一起上课,且需要区分次序(即多名教师的优先级)
    是否可应对变化:可以
    代价:需要将工厂、图形化GUI、App中的泛型类型修改,代价一般
    修改方法:将所有具体化实现CourseEntry的地方的泛型类型修改
    HIT 软件构造 lab3
    图表 63 可选择输入几名教师
    HIT 软件构造 lab3
    图表 64 多个教师的Menu选择
    3.14 Git仓库结构
    请在完成全部实验要求之后,利用Git log指令或Git图形化客户端或GitHub上项目仓库的Insight页面,给出你的仓库到目前为止的Object Graph,尤其是区分清楚314change分支和master分支所指向的位置。
    4 实验进度记录
    请使用表格方式记录你的进度情况,以超过半小时的连续编程时间为一行。
    每次结束编程时,请向该表格中增加一行。不要事后胡乱填写。
    不要嫌烦,该表格可帮助你汇总你在每个任务上付出的时间和精力,发现自己不擅长的任务,后续有意识的弥补。
    日期 时间段 计划任务 实际完成情况
    4-15 14:00-17:30 完成抽象化构想 完成
    4-18 10:00-12:00 完成PlanningEntry接口设计 完成
    4-21 – 5-03 19:00-22:00 完成App之前的全部内容 完成
    5-6 – 5-10 19:30-20:30 完成App 完成
    5-11 – 5-16 19:30-21:30 完成修改和部分报告 完成
    5-17 14:00-19:00 完成3.13 完成
    5-18 19:00 – 21:00 完成报告,完成全部内容 完成
    5 实验过程中遇到的困难与解决途径
    遇到的难点 解决途径
    抽象困难

    认真阅读实验手册, 加大抽象力度
    位置放置在子类中难以在父类中调用

    将位置设为List放入父类中
    控制台输入有问题

    修改时间格式
    6 实验过程中收获的经验、教训、感想
    6.1 实验过程中收获的经验和教训
    6.2 针对以下方面的感受
    (1) 重新思考Lab2中的问题:面向ADT的编程和直接面向应用场景编程,你体会到二者有何差异?本实验设计的ADT在五个不同的应用场景下使用,你是否体会到复用的好处?
    (2) 重新思考Lab2中的问题:为ADT撰写复杂的specification, invariants, RI, AF,时刻注意ADT是否有rep exposure,这些工作的意义是什么?你是否愿意在以后的编程中坚持这么做?
    (3) 之前你将别人提供的API用于自己的程序开发中,本次实验你尝试着开发给别人使用的API,是否能够体会到其中的难处和乐趣?
    (4) 在编程中使用设计模式,增加了很多类,但在复用和可维护性方面带来了收益。你如何看待设计模式?
    (5) 你之前在使用其他软件时,应该体会过输入各种命令向系统发出指令。本次实验你开发了一个解析器,使用语法和正则表达式去解析输入文件并据此构造对象。你对语法驱动编程有何感受?
    (6) Lab1和Lab2的大部分工作都不是从0开始,而是基于他人给出的设计方案和初始代码。本次实验是你完全从0开始进行ADT的设计并用OOP实现,经过五周之后,你感觉“设计ADT”的难度主要体现在哪些地方?你是如何克服的?
    (7) “抽象”是计算机科学的核心概念之一,也是ADT和OOP的精髓所在。本实验的五个应用既不能完全抽象为同一个ADT,也不是完全个性化,如何利用“接口、抽象类、类”三层体系以及接口的组合、类的继承、设计模式等技术完成最大程度的抽象和复用,你有什么经验教训?
    (8) 关于本实验的工作量、难度、deadline。
    (9) 到目前为止你对《软件构造》课程的评价。

(1) 二者的应用场景不同, 开发时候的思维也不同, 需要考虑的抽象方法也不同.
通过复用,我认为大大降低了我的工作量, 虽然由于不熟练并没有节约太多时间,但是通过练习想必是很有成效的
(2) 这些工作能够保证ADT的正确性,当发现问题时修改的逻辑会很简单
我愿意在以后的编程中时刻保证这样做
(3) 开发API给别人用是一个十分困难的过程,不仅仅要求其正确性,还需要其他人能够理解自己的想法,学会用法,但是如果能够帮助到他人的开发甚至能够通过这些赚钱是一个十分好的方法
(4) 我原本比较抵触设计模式,认为其没有什么意义,但是在自己开发的过程中体会到了设计模式的好处,认为它存在的意义十分重大,使用起来对于维护和改变会有很大的帮助
(5) 这些语法驱动器能够更加准确的识别文件中的内容,相比用if-else这种方法识别,效率大大提高了
(6) ADT的设计难度主要在于设想与实现的不同步。首先抽象十分困难,初次抽象出来的内容和最终的实可能会有很大出入,需要我们在开发过程中不断去完善自己的设想
(7) 计算机是一个造*和复用*的过程,每辆车的*不同,但也有相似之处,我们在造*的时候应该学会尽量将*的共同点凸显出来,降低自己的工作量
(8) 本次实验工作量巨大,难度也极高,不得不使用lateday
(9) 目前的软件构造课个人认为虽然讲的还比较浅,但是受益匪浅,锻炼了自己一直想学但是懒得学的Java语言,同时了解了很多软件设计的方法,让我有了实习的底气(大一结束我姐姐让我去她公司实习我没敢去,感觉自己啥也不会)