教学班级:005
项目地址:https://github.com/gzhGit/Intersectpro
项目 | 内容 |
---|---|
这个作业属于哪个课程 | 班级博客 |
这个作业的要求在哪里 | 结对项目 |
我在这个课程的目标是 | 学会团体和个人的软件开发方式 |
这个作业在哪个具体方面帮我实现目标 | 结对编程,体会合作 |
在开始实现程序之前,在下述 PSP 表格记录下你估计将在程序的各个模块的开发上耗费的时间。
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | ||
.Estimate | 估计这个任务需要多少时间 | 40 | 40 |
Development | 开发 | ||
·Analysis | 需求分析 (包括学习新技术) | 600 | 没有具体计算 |
·Design Spec | 生成设计文档 | 60 | 60 |
·Design Review | 设计复审 (和同事审核设计文档) | 10 | 10 |
·Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 10 | 10 |
·Design | 具体设计 | 20 | 0 |
·Coding | 具体编码 | 400 | 没统计 |
·Code Review | 代码复审 | 30 | 30 |
·Test | 测试(自我测试,修改代码,提交修改) | 120 | 120 |
Reporting | 报告 | ||
·Test Report | 测试报告 | 20 | 20 |
·Size Measurement | 计算工作量 | 20 | 20 |
·Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 60 | 60 |
看教科书和其它资料中关于 Information Hiding,Interface Design,Loose Coupling 的章节,说明你们在结对编程中是如何利用这些方法对接口进行设计的。
Information Hiding:对这一项应用比较少,所有类的属性和方法基本都是public,没有特别隐藏的方法或者变量。
Interface Design:只是创建一个能工作的应用程序是不够的。 用户期待直观的,吸引人的,强壮的应用。所以我们采用gui来完成与用户的交互。图形界面简单直接,易于操作。
Loose Coupling:很多不需要交流的参数和变量都封装在模块单元内部,不用被其他单元知晓,其他模块单元只需要知道提供的函数接口需要的数据类型,以及返回的数据类型。
计算模块接口的设计与实现过程。设计包括代码如何组织,比如会有几个类,几个函数,他们之间关系如何,关键函数是否需要画出流程图?说明你的算法的关键(不必列出源代码),以及独到之处。
我们在core模块中,为点、线、圆各建了一个类。其中,线分为直线、线段、射线,这三种都属于线这个类,用类中的一个整型变量来区分(0-直线,1-射线,2-线段)。然后线与线求交点,然后线与圆求交点,然后圆与圆求交点三个函数(直线、线段、射线都属于线,用同一个函数处理,在求出交点后,根据射线和线段的性质对交点取舍)。这些外部单元模块不需要知道,core向外提供了三个重载函数solve作为借口,外部模块只需要按头文件中的函数声明顺序输入参数即可(输入的参数就和结对项目中给的样例是一样的,比如直线就输入一个字符‘L’,四个整型代表两个点坐标,采用这样的标准输入来降低耦合度)。
画出 UML 图显示计算模块部分各个实体之间的关系。
计算模块接口部分的性能改进。记录在改进计算模块性能上所花费的时间,描述你改进的思路,并展示一张性能分析图(由VS 2015/2017的性能分析工具自动生成),并展示你程序中消耗最大的函数。
我们起初用来存储几何类型数据信息的数据结构是set容器,但是set容器是一个基于红黑树的容器,他需要维护树结构的平衡和顺序,这会带来时间开销,然而这些功能对于这次的项目是没有必要的,所以我们又换用了vector容器。vector容器相当于就是一个动态数组,他的插入、删除速度要由于set,但是数组扩容时,vector需要复制整个数组,也需要大量的时间开销。vector还有一个致命的问题。在插入几何对象时需要判断这个集合对象是否已经存在容器中,要解决这个问题,vector需要遍历一遍整个数组,在分析图中我们也可以看到,在插入点时,为了避免插入重复点,需要大量时间遍历数组,占到了90%以上的时间开销。于是我们决定使用hash结构来存储几何类型,可以避免对容器的遍历
看 Design by Contract,Code Contract 的内容:
http://en.wikipedia.org/wiki/Design_by_contract
http://msdn.microsoft.com/en-us/devlabs/dd491992.aspx
描述这些做法的优缺点,说明你是如何把它们融入结对作业中的。
优点:
(1)编写者和使用者都可以得到足够的信息。
(2)对于编写者来说,明确接口功能,检查预期行为,帮助debug,缩小了检测时间的花销。
(3)对于使用者来说,必要的有关接口的信息,给了使用者正确的使用方法。
缺点:编写需要额外的时间开销。
计算模块部分单元测试展示。展示出项目部分单元测试代码,并说明测试的函数,构造测试数据的思路。并将单元测试得到的测试覆盖率截图,发表在博客中。要求总体覆盖率到 90% 以上,否则单元测试部分视作无效。
首先我们考虑所有的几何类型组合,共有10种(从4个选2个,比如LC相交,从4个选1个,比如LL相交),再根据分支覆盖情况添加测试样例。
计算模块部分异常处理说明。在博客中详细介绍每种异常的设计目标。每种异常都要选择一个单元测试样例发布在博客中,并指明错误对应的场景。
我们设计了4种异常情况:
(1)输入几何类型字符不合法,输入了L, R, S, C之外的几何类型
(2)输入的点的坐标不在规定范围内
(3)输入的直线的两个端点重合
(4)输入的圆的半径r小于等于0
界面模块与计算模块的对接。详细地描述 UI 模块的设计与两个模块的对接,并在博客中截图实现的功能。
ui模块如图所示,有两种输入方式:(1)直接从文件导入; (2)输入几何对象数据信息来增加集合对象。
用户输入数据后,ui模块调用core模块的solve函数接口,将这些数据传到core模块中去运算,core将算出来的交点坐标返回给ui模块,ui在下方的显示界面上绘制出几何图形和交点。
界面模块的详细设计过程。在博客中详细介绍界面模块是如何设计的,并写一些必要的代码说明解释实现过程。
我们使用了qt的信号与槽机制来实现以上功能。首先我们所用的组件有6个push button,分别是上图中给出的6个功能,每个push button对应一个被用户点击都会发出一个clicked()信号(这个信号函数由qt的库提供),我们的工作主要是包这些clicked()对应到相应的功能上,也就是qt的信号与槽机制。以下是这几个槽函数的函数声明以及6个push botton的声明,以及注释说明每个槽函数具体干什么。
private:
QPushButton *btnFile;
QPushButton *btnHelp;
QPushButton *btnLine;
QPushButton *btnCycle;
QPushButton *btnInfile;
QPushButton *btnAbout;
private slots:
void on_btnFile(bool checked); //btnfile按钮的clicked(bool)信号的槽函数,点击将会进入选择要导入的文件路径
void on_btnHelp(bool checked);//btnHelp按钮的clicked(bool)信号的槽函数,点击将会跳出一个文本窗口介绍本UI界面
void on_btnLine(bool checked); //btnHelp按钮的clicked(bool)信号的槽函数,点击将会跳出一个窗口,用户在这个窗口输入想要插入的Line的参数
void on_btnCycle(bool checked); //btnCycle按钮的clicked(bool)信号的槽函数,点击将会跳出一个窗口,用户在这个窗口输入想要插入的Cycle的参数
void on_btnInfile(bool checked); //btnInfile按钮的clicked(bool)信号的槽函数,点击将会把先前读入的文件信息转化为几何图形绘制在画布上。
void on_btnAbout(bool checked); //btnAbout按钮的clicked(bool)信号的槽函数,点击将会跳出一个文本窗口,窗口中显示当前已输入几何图形的数字信息。
描述结对的过程,提供两人在讨论的结对图像资料(比如 Live Share 的截图)。关于如何远程进行结对参见作业最后的注意事项。
说明结对编程的优点和缺点。同时描述结对的每一个人的优点和缺点在哪里(要列出至少三个优点和一个缺点)。
优点:(1)两个人起到了一个相互监督的作用,有助于双方(尤其是在写代码的一方)集中于工作。
(2)两个人一起工作,可以随时讨论程序算法、架构等问题,集思广益。
(3)一个人在写代码的同时,另一个人在debug,极大的降低了出bug的可能性。
缺点:需要两个人有比较默契的合作,两人实力差距也不应过大。