软件构造Lab3基本流程指导及重难点分析

Posted dugudashen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了软件构造Lab3基本流程指导及重难点分析相关的知识,希望对你有一定的参考价值。

本篇文章旨在引导HIT软件构造Lab2的基本流程并进行一些重难点的解释,总体内容偏向基础,出发点是在实验过程中我遇到了很多问题并花了大量时间才解决,希望可以帮助大家更好地完成实验。

Lab3是所有实验中内容最多、耗时最长的一个实验,而且自由度很高,不好给出固定的设计思路,这里稍微举例说明我个人的大体设计思路做一个参考,并会介绍首次涉及到的工具使用。

实验目标:通过对一个规模不小的软件从零实现,训练针对可复用性和可维护性的技巧,同时进一步训练java面向对象设计思想及ADT的设计和熟练运用。

总体概述:本实验要求实现一个“计划项管理程序”,其中重点在于计划项有很多种,每种计划项有自己独特的内容和功能,计划项之间在一些方面有共性,在一些方面有差异性。考虑到如果将每种计划项都独立出来单独实现这种方式需要编写大量重复无用代码十分冗长,我们需要将计划项之间的共性合并只实现一次,差异性分开分别实现。例如飞机计划项和课程计划项的时间信息存在共性,都是一个起始时间和一个结束时间组成,而位置信息有差异性,飞机计划项有起飞地点和降落地点而课程计划项只有一个上课地点。实验手册中给出了一些方法,在具体实现中很多细节也存在很多方式,自由度很高,实现起来也非常个人化。下面给一个我的大体实现,仅提供一个参考,理解了其中的含义之后还是需要自己思考自己设计。

我的实现:(选择飞机1、高铁2、课程4三种计划项)一个计划项接口,三种接口的实现类分别对应三种计划项。控制时间的类有两个,一个对应开始结束时间对,另一个对应一个时间序列。控制位置的类有两个,一个对应单个地点,另一个对应地点序列。时间和地点的类均使用委托的设计模式在对应计划项实现类中发挥作用,例如飞机计划项实现类中声明了控制时间类一和控制位置类二。三种计划项分别实现三个资源类。计划项的状态控制在接口层实现,首先另写一个状态类,其中包含各个状态之间的转移合法性问题,之后在接口层使用委托的设计模式声明状态类,利用状态类实现状态控制。

考虑完上述重点问题后还有一些直接一些的问题,比如展示板设计及其可视化、添加功能、外部客户端程序、基于语法的读入、新的变化,下面依次说明这些问题。

1.展示板设计

传入参数为计划项集合,声明链表数据结构,扫描一遍计划向集合,将符合时间要求的计划项提取出来放入链表中。需要注意的是,展示板需要区分“起点”“终点”这一对信息,还需要区分“已经起飞/到达”“尚未起飞/到达”这一对信息,两个两对情况交叉后会产生四种情况,需要做好标记,避免混淆。

2.展示板可视化

新建一个实现可视化类,在其中使用JTable工具实现信息的GUI可视化,要求传入参数是一个统一标准的字符串,由于三个计划项均要求最终显示表格信息,故只要传入参数均符合规则,可视化类便可以实现复用。难点在于JTable工具的使用,以下是我的实现,其中columnName数组存储表格标题信息,columnDate二维数组存储表格内容信息。

 1 import java.util.*;
 2 
 3 import javax.swing.*;
 4 
 5 import java.awt.BorderLayout;
 6 
 7 public class TestGui extends JFrame {
 8     private static final long serialVersionUID = 1L;
 9     private String[] columnName;
10     private String[][] columnDate;
11     public static void draw(String title, List<String> name, List<String> date) {
12         new TestGui(title, name, date);
13     }
14     TestGui(String title, List<String> name, List<String> date) {
15         super(title);
16         /*
17         此处设置填充columnDate和columnName数组
18         */
19         JTable table = new JTable(columnDate, columnName);
20         init();
21         addComponent(table);
22         setVisible(true);
23     }
24     private void init() {
25         setSize(600, 400);
26         // 设置窗口位置居中
27         setLocationRelativeTo(null);
28         // 设置布局
29         setLayout(new BorderLayout());
30         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
31     }
32     private void addComponent(JTable table) {
33         JScrollPane scrollPane = new JScrollPane(table);
34         add(scrollPane, BorderLayout.CENTER);
35     }
36 }

3.添加功能

3.1检测一组计划项之间是否存在位置独占冲突

实现方式是将所有计划项作为集合传入,二重循环进行两两比较,若地点相同且时间段存在重合,则存在位置独占冲突。这里提供一个时间段存在重合的判断方法,设A项目时间为a到b,B项目时间为c到d,则存在重合时间当且仅当“b大于c且a小于c或d大于a且c小于a”。据此判断是否重合即可。

3.2检测一组计划项之间是否存在资源独占冲突

将所有计划项作为集合传入,二重循环两两比较,将计划项中的资源提取出来进行比较,若该计划项仅包含一个资源则仅需要进行一次比较,而拥有多资源的计划项需要循环选定两个计划项的所有资源,只要存在一个资源重合则整体存在冲突。以上存在冲突建立在时间重合的情况下,时间重合判定继续沿用3.1提供的方法即可。

3.3提取面向特定资源的前序计划项

传入所有计划项和特定资源和特定计划项,循环扫描所有计划项,将资源存在的计划项中所有时间比特定计划项早的计划项提取出来,再将提取出来的计划项进行排序,找到时间最晚的计划项,即为所求。时间的比较方法不出意外之前已经在时间类中实现了,如果没有实现则现在实现一遍,方法是从年月日时分秒依次判断下来,按实际情况判断出时间先后。

4.外部客户端程序

之前两个实验都设计过类似的命令行交互客户端程序,即输出必要提示信息如用户命令输入格式表,之后读取用户输入的命令并根据此命令执行程序并给予反馈,输出结果。

5.基于语法的读入

需要文件读入,并依据正则表达式的相关内容编写程序,使程序可以读入一个规定格式的字符串。方法是首先逐行读入文件内信息,分别处理每行信息格式是否匹配,若匹配则提取本行信息并执行,若中途出现文本读入不符合规定的情况返回NULL,若文本读入全部正确则在读完所有计划项后整合成一个计划项集合返回,以供后续使用。逐行读入并进行正则表达式判断示例如下。

1     String s = book.get(i);
2     if (Pattern.matches("^Flight:(.*?)", s) == false)
3         return null;

6.新的变化

你设计软件可复用性和可维护性的好坏决定了本题目的工作量,若可复用性和可维护性良好,则可以在上层更改较少的内容即可实现要求功能,若可复用性和可维护性不够好,可能需要在底层更改非常多的内容,本节完全依赖于之前自由度很高的实现,便不再给出一般性做法,若发现无法轻松达到修改要求,可以考虑重构之前的设计,结合本次修改的内容应该可以将之前的设计做得更好。

 

 

关于git使用:

实验手册上已经给出了关于切换分支的详细做法,注意,一定要在主任务完成后先切换分支再进行额外任务的编写,若没有切换分支就开始额外任务的编写会导致后续无法切换分支,进而可能导致git仓库目录结构混乱。

以上是关于软件构造Lab3基本流程指导及重难点分析的主要内容,如果未能解决你的问题,请参考以下文章

Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段

Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段

软件构造Lab3中关于时间相关类的设计

软件构造Lab3中关于时间相关类的设计

软件构造Lab3中关于时间相关类的设计

第3周学习指导及要求(2017.9.6-2017.9.12)