Author: 17373051 郭骏

3.28添加:4.计算模块接口的设计与实现过程部分,PairCore实现的细节

项目 内容
这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健)
这个作业的要求在哪里 结对项目作业
我在这个课程的目标是 学习软件工程的开发知识,培养工程化开发能力
这个作业在哪个具体方面帮助我实现目标 通过实操掌握结对开发基础

1.前言

给定 N 个几何图形,询问平面中有多少个点在至少 2 个给定的图形上。

在此处先展示Code Quality Analysis的零警告图片。

2.PSP表格

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 5 5
· Estimate · 估计这个任务需要多少时间 5 5
Development 开发 390 570
· Analysis · 需求分析 (包括学习新技术) 60 60
· Design Spec · 生成设计文档 20 20
· Design Review · 设计复审 (和同事审核设计文档) 5 5
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 5 5
· Design · 具体设计 60 120
· Coding · 具体编码 120 120
· Code Review · 代码复审 60 60
· Test · 测试(自我测试,修改代码,提交修改) 60 180
Reporting 报告 70 100
· Test Report · 测试报告 30 60
· Size Measurement · 计算工作量 10 10
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 30 30
合计 465 675

3.接口设计思想

  • 信息隐藏

    这条原则指导我们,应当将类的属性私有化,通过访问函数来实现,并且使用接口来连接层与层。我们在设计的过程中,做到了将类的属性全部私有化。接口的实现方面,我们使用类的部分公有函数作为接口,做到了类与类之间的交互。

  • 接口设计

    我们在设计过程中,通过Point—Line/Circle—Core三层类的结构环环相扣,每两层之间使用有限的公有函数进行交互。Line和Circle有互相使用对方求交点的方法,能够轻松的调用交点求解程序,Line也包含了线段、射线和直线,在外层写程序时不用关心到底是哪两种图形在求交点。

  • 松耦合

    类与类、层与层之间有着较好的隔离,如果出现问题或者需要增加需求,只需要修改一个类中的代码,而不需要去修改其调用的其他类。如Line和Circle,虽然需要互相求交点,但是修改其中一个类的代码,可以无需改动另外一个类,因为接口是完善的,类之间的耦合度也是低的。

在C++中,我们并没有使用抽象类的特性来帮助我们构建接口,因为抽象类在作为函数参数时的支持并不够方便。在此提到的“接口”,指的是每个类的公有方法。

4.计算模块接口的设计与实现过程

我们的程序由Point类打底,代表解题过程中的点,可以是线段/射线的端点,也可以是图形之间的交点。我们为其预设了比较函数和赋值方法,作为程序的基础。

然后是Line类和Circle类。Line类包含线段、射线和直线,作为基础题部分的解题骨干。Line类的核心方法是Line::getIntersect(Line l),可以帮助我们轻松求出两条线之间的交点。Circle类是圆类,用于附加题。该类有对直线和圆求交点的方法。

主类为PairCore。这个类中包含了命令行参数分析函数,输入正则匹配函数,以及求交点输出到文件的函数。有PairCore::parser(int argc, char* argv[])方法,用于处理命令行参数的输入,解析方式是简单的字符串相等的条件判断。PairCore::text_handle()方法是用于从文件中读入数据,按行读入,第一行是数字,之后的每一行采用正则表达式的方式进行读取,如果格式与正则表达式不匹配则返回报错。同时我们也需要对输入范围进行特判。PairCore::getIntersectionCount()是用于计算几何图形交点的函数,其中包含三个循环,分别用于计算线与线、线与圆、圆与圆的交点。

本次作业中的核心函数,也是和上次作业很不一样的地方,就是判断求出来的点是否是两个图形的交点。由于线段、射线的范围有限制,所以我们需要判断点是否在线上。我们有函数Line::isOnline(Point p)来判断点是否在线上。判断的方法是与线的两个端点进行比较。

同时,我们需要判断输入的线是否重合,即便在同一条直线上,也有可能是没有交点或者有一个交点。我们有函数Line::relation(Line l)来判断两条线的关系。如果两条线在同一直线上,则我们会对两条线的端点坐标进行判断,从而能够判断出他们真实的交点个数。

算法的独到之处在于,早早为Point类写好了比较函数,将此后的许多位置关系判断转化为端点坐标的位置判断,简化了问题。

5.UML图

UML类图如下所示。

6.性能改进

我们使用VS的性能分析器对2000条线、500个圆的情况进行了分析,得到的图如下所示:

可以看到,在Line::getIntersect这个方法上耗费的CPU达到32%,让我们感到不可思议。我们进入代码之后,查看了语句的CPU使用率。

可以看到,语句大部分时间花在了对vector的创建、修改和返回上。由于两条线之间的交点只能是1个或者0个,所以我们可以不用vector<Point>作为返回值,而是用Point作为返回值,并判断该Point是否存在。修改之后的占比如图所示。

我们在优化上大概耗费了20分钟。

7.契约式设计

契约式设计要求设计者对软件设计正式、准确、可验证的接口规范,定义了先验条件、后验条件和不变式,这些规范称为“契约”。

这种方法的优点:

  • 通过规范化的注释,能够直接验证程序正确性。
  • 设计时着重功能而非具体实现,不用担心具体的实现流程。
  • 明确接口的功能之后,设计者和开发者都能够得到足够的信息。

这种方法的缺点:

  • 程序的正确性验证有时代价会非常大,甚至可能无法检错。
  • 正确而规范的设计十分困难,会出现满足设计而不满足功能的情况。
  • 存在一些难以或无法用契约设计的功能。

在结对作业中,这种思想确实可以让我们写出正确性较为完备的程序,但是却难以帮助我们对程序进行优化。同时,在从设计到实现的过程中,我们常常需要绞尽脑汁,甚至不得已去修改设计。因而,在结对的过程中,我们没有过分依赖契约式设计,只是做到了一般的设计—开发的流程。

8.单元测试展示

部分单元测试代码展示:

单元测试通过截图:

单元测试覆盖率截图:

我们构造测试数据的思路是:从一般到特殊,从简单到复杂,从白箱到黑箱。

我们的测试代码有题目的样例代码、最简单情况的代码、特殊情况(重合、平行、端点相交、射线相背等)的样例设计,以及一些能够触发异常的样例。此外,我们还使用随机数据生成器生成了一点随机且复杂的情况加入测试,用于检测我们的考虑是否完备。

9.异常处理说明

我们设计了13种异常,每种异常都有其对应的错误码。错误码和异常的对应关系在程序中有所体现,代码如下:

错误代码 错误信息 测试样例
-1 线段之间存在重合 2
S 0 0 2 2
S 1 1 3 3
-2 线段和射线之间存在重合 2
S 0 0 2 2
R 1 1 3 3
-3 射线之间存在重合 2
S 0 0 2 2
S 1 1 3 3
-4 直线与某条线重合 2
L 0 0 2 2
S -1 -1 -2 -2
-5 圆与圆重合 2
C 0 0 2
C 0 0 2
-6 输入的两个交点重复 1
L 1 1 1 1
-7 坐标超出(-100000,100000)的范围 1
L 100000 1 1 1
-8 输入圆的半径不大于0 1
C 0 0 -2
-9 分析图形信息时出错 1
asdfg
-10 分析图形个数时出错 L 1 1 2 2
-11 几何图形个数与输入的数目不匹配 2
L 1 1 2 2
-12 多余的不在末尾的换行符 2
L 2 2 3 3

L 0 5 5 0
-13 命令行参数错误 intersect.exe -p point.txt

如果在命令行模式下发生异常,则程序会将错误信息输出到同目录下的error.txt中。

10.界面模块设计

界面模块采用C#的Winform来开发。由于这是我们第一次使用C#,也是第一次开发GUI程序,在设计上难免会存在一些不足。

界面设计如图所示,我们的界面模块有两个窗口。

第一个窗口(Form1)是输入输出图形信息的窗口。如果GUI使用不当,会有相应的错误提示。右边的列表是现有的图形信息,可以通过鼠标点选来进行删除。

从文件导入之后不会直接开始绘制,而是将文件中的点信息加入到现有的点列表中,提供了相对高的灵活性和可操作性。

我们确实支持图形的绘制,也支持图形的添加和删除,但是这两个过程在我们的界面中是分离的,即没有做到像GeoGebra一样能够实时绘制图形和交点。

第二个窗口(Form2)是我们的绘制结果窗口。该窗口使用Winform的Panel进行绘制,整个绘制过程为造轮子过程,即没有成熟的坐标系模块供我们使用,所以效果相对简陋,且不支持缩放和平移。不过由于结对编程只有短短的两周,且中间经历了很多别的作业,所以没有在此处过于苛求。程序默认将所有的图形都画进窗口中,所以如果图形的横纵轴跨度较大,则观感会欠佳。

轮子中的关键代码是如何掌握好窗口的边界位置。我们相当于要将所有图形的坐标范围(minx,miny)-(maxx,maxy)映射到我们的画板(0,0)-(720,720)上。映射过程的核心代码如下:

float k, dx, dy;
if (maxx - minx < 1 && maxy - miny < 1)
{
k = 1;
dx = minx;
dy = miny;
}
else
{
if ((maxx - minx) > (maxy - miny))
{
k = maxx - minx;
dx = minx;
dy = miny - (maxx - maxy - minx + miny) / 2;
}
else
{
k = maxy - miny;
dx = minx - (-maxx + maxy + minx - miny) / 2;
dy = miny;
}
}

这里的k是缩放比例,dx和dy是x轴和y轴的平移距离。对于每个点的坐标,我们只需要进行如下变换:x = (x0 - dx) * 720 / k, y = (y0 - dy) * 720 / k即可。

11.模块对接

dll为前端留下了两个接口,分别用于GUI展示和命令行测试。

/*GUI展示
dll从同目录下的lines.pair按格式读入几何图形的信息,
求解后将得到的点的坐标存入同目录下的points.pair文件。
函数的返回值>=0,代表交点个数。<0则代表出现异常,返回异常代码。
*/
int solve();
/*命令行展示
dll从同目录下的commands.pair按格式读入命令行参数,按要求处理。
函数的返回值>=0,代表交点个数。<0则代表出现异常,返回异常代码,不写文件。
报错部分的代码由前端完成,将错误信息存在同目录下error.txt中。
*/
int command();

可以看到这两个接口的交互几乎全部依赖于文件和返回值,没有进行参数传递。

主要的原因在于,C#和C++的标准有诸多不同,比如C#不支持指针,char为两个字节长度,string类和C++的string类不能公用等。我们尝试无论怎么传参数,都无法达到我们想要的效果,只能传一些简单的数字。所以我们干脆制定了文件读入的标准。

如果我们使用C++的GUI开发,可能不会出现这样的问题,这是我们需要反思的一点。

12.结对过程

结对过程主要通过QQ语音+Live Share的方式完成。由于网络原因,常常出现Live Share断线的情况,极大的影响了我们的工作效率。不过在我们的不懈努力之下,最终还是完成了本次作业。证据如下所示:

13.结对编程

  • 优点

    • 编程过程互相监督,不会存在摸鱼的情况,随时思考随时交流,思维更加集中
    • 两人共审同一份代码,对代码的质量和正确性都有更高的保证。
    • 两人一起工作,集思广益,对于困难的问题可能会更快产出解答。
  • 缺点
    • 度过磨合期很困难,要互相习惯对方的编程速度、思维、风格。
    • 对于“驾驶员”来说,写代码的“领航员”过度插手可能会带来反效果。
结对人员 队友
优点 思维较快,思考更迅速连贯 思考全面,单元测试完善
缺点 难以习惯队友的代码风格、编程习惯等,磨合期较难受 节奏难以同步

14.附加题:支持松耦合

我们选择交换dll的团队是(17373052, 17373053)团队。

他们的dll设计与我们大致相同,除了文件的命名方式以外,其他大致相同。

合并时遇到的问题有:

  • 他们并非由GUI和command两个函数构成,而是只有一个函数run(),由命令行参数进行区分。无论是否需要绘制,都会将点的信息存在points.txt中。我们修改了我们的读写方式,以适配他们的核心模块。
  • 他们的异常处理返回信息和我们不一样。他们的run()函数只定义了两种异常:输入异常和重合异常。我们为此修改了异常的返回信息。

经测试,命令行和GUI都可以正常使用。

后记:一点体会

BUAA 2020 软件工程 结对项目作业的更多相关文章

  1. BUAA 2020 软件工程 个人项目作业

    BUAA 2020 软件工程 个人项目作业 Author: 17373051 郭骏 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 个人项目作业 ...

  2. BUAA软件工程结对项目作业

    BUAA软件工程结对项目 小组成员:16005001,17373192 1.教学班级和项目地址 项目 内容 这个作业属于哪个课程 博客园班级连接 这个作业的要求在哪里 结对项目作业 我在这个课程的目标 ...

  3. BUAA 软工 结对项目作业

    1.相关信息 Q A 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 结对项目作业 我在这个课程的目标是 系统地学习软件工程开发知识,掌握相关流程和技术,提升 ...

  4. BUAA软工-结对项目作业

    结对项目作业 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 结对项目作业 我在这个课程的目标是 通过这门课锻炼软件开发能力和经验,强化与他人合作 ...

  5. BUAA 2020 软件工程 个人博客作业

    BUAA 2020 软件工程 个人博客作业 Author: 17373051 郭骏 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 个人博客作业 ...

  6. BUAA软件工程个人项目作业

    BUAA软件工程个人项目作业 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 个人项目作业 我在这个课程的目标是 学习软件开发的流程 这个作业在哪 ...

  7. BUAA 2020 软件工程 热身作业

    BUAA 2020 软件工程 热身作业 Author: 17373051 郭骏 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 第一次作业-热身! ...

  8. BUAA 2020 软件工程 提问回顾与个人总结

    BUAA 2020 软件工程 提问回顾与个人总结 Author: 17373051 郭骏 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 提问回顾 ...

  9. 【BUAA 软工个人项目作业】玩转平面几何

    BUAA 软件工程个人项目作业 项目 内容 课程:2020春季软件工程课程博客作业(罗杰,任健) 博客园班级链接 作业:BUAA软件工程个人项目作业 作业要求 课程目标 学习大规模软件开发的技巧与方法 ...

随机推荐

  1. Mysql常用sql语句(15)- cross join 交叉连接

    测试必备的Mysql常用sql语句 https://www.cnblogs.com/poloyy/category/1683347.html 前言 交叉连接就是求多表之间的笛卡尔积 讲道理..这个我都 ...

  2. 转:C#根据条件设置datagridview行的颜色

    1 private void LoadData() 2 { 3 DataTable tblDatas = new DataTable(); 4 tblDatas.Columns.Add("I ...

  3. ysoserial CommonsColletions6分析

    CC6的话是一条比较通用的链,在JAVA7和8版本都可以使用,而触发点也是通过LazyMap的get方法. TiedMapEntry#hashCode 在CC5中,通过的是TiedMapEntry的t ...

  4. pytest+allure基础知识

    介绍 pytest是基于unittest开发的另一款更高级更好用的单元测试框架 支持参数化 执行测试过程中可以将某些测试跳过(skip),或者对某些预期失败的case标记成失败 支持运行由 nose, ...

  5. 10.6Java学习

    1.类,对象,方法的定义.2.标识符分为两类:关键字/常见的基本类型:boolean(布尔型),byte(字节型),char(字符型),double(双精度),float(浮点),int(整型),lo ...

  6. Jenkins 进阶篇 - 任务关联

    有时候我们的一个任务里面会进行很多的步骤,例如构建一个后端的 Java 服务,可能会有代码静态扫描,静态扫描通过后会打包成 jar 或者 war 文件,打包成功后可能还会对制品进行存档备份,然后可能会 ...

  7. 我爬取交通学博士付费的GIS资源,每年被动收入2w很简单?

    目录 1.背景介绍 2.技术路线 3.数据结果 4.数据分析 5.总结 6.后记 1.背景介绍 某周末闲来无事,顺手打开了CSDN,看到了一个人发布的收费GIS资源,售价是¥19.9,POI数据也有人 ...

  8. 微信小程序 创建自己的第一个小程序

    * 成为微信公众平台的开发者 注册 https://mp.weixin.qq.com * 登录 https://open.weixin.qq.com/ * 开发者工具下载 https://develo ...

  9. appium和selenium不同与相同之处

    原文来自: https://www.cnblogs.com/zhengshuheng/p/6370398.html selenium是web端的自动化,appium是app端的自动化,它继承了webd ...

  10. P7115-[NOIP2020]移球游戏【构造】

    正题 题目链接:https://www.luogu.com.cn/problem/P7115 题目大意 \(n+1\)个柱子,前面\(n\)个上面各有\(m\)个球,球有\(n\)种颜色,每种\(m\ ...