zoukankan      html  css  js  c++  java
  • 结对项目作业

    项目 内容
    这个作业属于哪个课程 班级博客
    这个作业的要求在哪里 作业要求
    我在这个课程的目标是 学好并应用好软件工程
    这个作业在哪个具体方面帮助我实现目标 学习结对编程
    项目地址 使用队友仓库:https://github.com/Reliacrt/INTERSECTION_GUI/
    作业正文 如下

    看教科书和其它资料中关于 Information Hiding,Interface Design,Loose Coupling 的章节,说明你们在结对编程中是如何利用这些方法对接口进行设计的。

    信息隐藏:

    计算模块中暴露给其他模块的只有add_shape(line)、delete_shape(line)、get_shapelist()、intersect(Shape* ano)四个函数,其他模块不能调用其他函数,抛出异常、点的计算均只在计算模块可见;

    接口设计:

    为了能适应gui,设计了增加几何对象add_shape(line)、删除几何对象delete_shape(line)、获得已有几何对象集合get_shapelist()三个接口,intersect(Shape* ano)暴露给其他模块为了求交点;

    松耦合:

    其他模块只需提供输入即可在计算模块计算出所有交点。

    计算模块接口的设计与实现过程。设计包括代码如何组织,比如会有几个类,几个函数,他们之间关系如何,关键函数是否需要画出流程图?说明你的算法的关键(不必列出源代码),以及独到之处。

    类:

    一个抽象类(Shape),四个子类(Line、Circle、Segment、Radial,分别记录四种图形的信息),

    Point类(记录交点信息),RetPoints类(记录两个图形交点信息,可能0、1、2个点),ShapeList类(用于异常处理);

    函数:

    三个主要函数(用于求直线与直线、直线与圆、圆与圆的交点)

    inline RetPoints line_inter_line(Shape* s1, Shape* s2);
    inline RetPoints line_inter_circle(Shape* s1, Shape* s2);
    inline RetPoints circle_inter_circle(Shape* s1, Shape* s2);

    判断函数(判断交点是否在射线或直线上,如果不在的话就删除)

    inline RetPoints segment_constraint(Shape* s, RetPoints orig);
    inline RetPoints radial_constraint(Shape* s, RetPoints orig);

    inline bool on_radial(Point p, Shape* s);
    inline bool on_segment(Point p, Shape* s);

    与异常处理相关的函数:

    void add_shape(char* line);
    void delete_shape(char* line);

    inline char* decide_char(char* s, char* c);
    inline char* decide_int(char* s);
    inline void decide_more(char* s);

    add_shape函数是与外界的接口,传进输入(例如“C 1 1 1”),然后通过decide_char、decide_int、decide_more判断输入是否异常;

    delete_shape函数用于GUI模块删除某个几何对象,并且判断异常(没有被删除的对象);

    接口:

    RetPoints intersect(Shape* ano);

    vector<Shape*> get_shapelist();

    get_shapelist用于传出向量(所有new的对象(Line、Circle、Segment、Radial));

    四个类(Line、Circle、Segment、Radial)都有成员函数RetPoints intersect(Shape* ano),外部通过该函数来求两两几何对象的交点,外部可以通过set(去重)来存储交点信息。

    关键函数流程图:

    函数不复杂,可用文字表达:

    三个主要函数(用于求直线与直线、直线与圆、圆与圆的交点)用公式求交点即可;void add_shape(char* line)函数对line先判断格式(字符 数字 数字 ...),格式不对抛出异常,然后new相应的对象,与已有的几何对象比较,如果重合抛出异常,否则将该对象加入shapelist中;

    算法的关键:

    关键在于求两个几何对象的交点(特别是如果两条线段位于一条直线上,这两条线段可能不相交,即没有无穷多个交点,不用抛出异常);

    算法的独到之处:

    线段、射线可以看成直线,只需计算交点后判断交点是否位于线段或者射线之上即可,double的比较(eps)。

    阅读有关 UML 的内容:https://en.wikipedia.org/wiki/Unified_Modeling_Language。画出 UML 图显示计算模块部分各个实体之间的关系(画一个图即可)。

    计算模块接口部分的性能改进。记录在改进计算模块性能上所花费的时间,描述你改进的思路,并展示一张性能分析图(由VS 2015/2017的性能分析工具自动生成),并展示你程序中消耗最大的函数。

    在改进计算模块性能上花费60min;

    改进思路:

    改进之前两个几何对象的交点信息用vector记录,发现比较浪费时间和空间(最多两个交点),改建一个新类RetPoints来记录信息、改进之前判断两线是否重合通过化简A、B、C(求最大公因子),然后比较是否相等,改进之后可以直接取一条直线上的两点带入另一条线判断即可。

    性能消耗最大的函数:

    看 Design by Contract,Code Contract 的内容,描述这些做法的优缺点,说明你是如何把它们融入结对作业中的。

    Design by Contract:

    优点:获得更加优秀的设计,不会盲目、更清楚、更简单,更容易阅读、理解、找错,减少犯错,可靠性更高;

    缺点:需要时间来理解、需要时间来实践;

    Code Contract :

    优点:通过代码契约可以规范代码,同时符合契约的代码可以使用现有工具来进行检查正确性、生成等;

    缺点:理解契约需要花费时间、写代码受到限制,限制还没有很多软件支持契约;

    如何融入结对作业中:单元测试中使用断言,为了程序的可靠性、健壮性,对可能情况抛出异常,一个类、方法尽可能只解决一个任务。

    计算模块部分单元测试展示。展示出项目部分单元测试代码,并说明测试的函数,构造测试数据的思路。并将单元测试得到的测试覆盖率截图,发表在博客中。要求总体覆盖率到 90% 以上,否则单元测试部分视作无效。

    计算模块为CORE.cpp

    覆盖率:

    测试函数:

    测试的函数主要是RetPoints intersect(Shape* ano)函数(求两个几何对象交点)

    单元测试代码:

    测试数据思路:

    每种几何对象均涉及到,测试中间结果(两个几何对象交点个数和坐标),测试极端情况(两条线段、射线(在一条直线上)的交点),测试斜率无穷大,斜率为0,与圆相切,测试线段在圆中间等等。

    计算模块部分异常处理说明。在博客中详细介绍每种异常的设计目标。每种异常都要选择一个单元测试样例发布在博客中,并指明错误对应的场景。

    序列号 异常 目标 单元测试样例 说明
    1 Input char does not conform to four formats 避免出现输入格式错误 shapelist->add_shape("E 1 1 1"); 没有E这种格式
    2 Fewer inputs 确保输入数字数目符合要求 shapelist->add_shape("C 1 1"); 输入数字太少
    3 Leading 0 避免数字出现前导0 shapelist->add_shape("C 1 1 001"); 输入数字有前导0
    4 The input number does not meet the requirements 确保数字符合要求(范围、不会出现其他字符...) shapelist->add_shape("C 1 1 10000000"); 输入数字不符合要求
    5 More inputs 确保输入数字数目符合要求 shapelist->add_shape("C 1 1 1 1"); 输入数字太多
    6 Two point superposition 避免输入线的两点重合,无法计算 shapelist->add_shape("L 1 1 1 1"); 输入两点重合
    7 Circle radius is 0 避免圆的半径为0,无法计算 shapelist->add_shape("C 1 1 0"); 圆半径为0
    8 Infinite intersections 避免出现无穷多个点,程序不会终止 shapelist->add_shape("C 1 1 1"); shapelist->add_shape("C 1 1 1"); 无穷多个交点
    9 Deleted element is empty GUI模块删除对象时当前平面上有该对象 shapelist->delete_shape("C 1 1 1"); 没有删除对象

    界面模块的详细设计过程。在博客中详细介绍界面模块是如何设计的,并写一些必要的代码说明解释实现过程。

    控件

    • 输入文本框
    • Insert按钮
    • Delete按钮
    • 绘图区

    回调函数

    • text_cb: 保存输入数据的指针
    • bt_insert_cb: 向ShapeList中插入图形,若出错打印错误信息
    • bt_delete_cb: 从ShapeList中删除图形,若出错打印错误信息
    • update_canvas: 绘图区重绘函数

    绘图(即update_canvas函数)

    1. 初始化绘图区;
    2. 绘制x、y轴;
    3. 遍历Shape的数组,绘制每个Shape
      • 坐标转换
      • 绘制图形
    4. 遍历Point的数组,绘制每个交点
      • 坐标转换
      • 绘制图形

    坐标转换

    // unit求解每单位坐标的像素数
    inline double unit(int w, int h, double mx, double my)
    {
        // w: width
        // h: height
        // mx: 最大绘制图形的横坐标
        // my: 最大绘制图形的纵坐标
    	double xu = (w / 2.0) / (mx + 5);
    	double yu = (h / 2.0) / (my + 5);
    	return xu < yu ? xu : yu;
    }
    // trans转换图形的坐标到canvas的坐标
    inline double trans(double x, int w, double un)
    {
        // x: x或y坐标
        // w: 宽度或高度
        // un: unit
    	return w / 2.0 + x * un;
    }
    

    上述两个函数就实现了将某个点数学的x、y坐标转换为canvas的坐标的功能。

    界面模块与计算模块的对接。详细地描述 UI 模块的设计与两个模块的对接,并在博客中截图实现的功能。

    模块对接

    1. 使用CORE模块导出得ShapeList存储各个Shape
    2. 遍历ShapeList使用Shape类的intersect接口计算Point集合
    3. 使用ShapeList的add_shape和delete_shape添加删除某个Shape

    如图,绘制了圆、直线、线段、射线及其交点

    描述结对的过程,提供两人在讨论的结对图像资料(比如 Live Share 的截图)。

    过程:一者提出设计方案,一者进行其实现,大致按照了领航员的结对方式。

    截图:

    看教科书和其它参考书,网站中关于结对编程的章节,例如:http://www.cnblogs.com/xinz/archive/2011/08/07/2130332.html ,说明结对编程的优点和缺点。同时描述结对的每一个人的优点和缺点在哪里(要列出至少三个优点和一个缺点)。

    结对编程的优点:

    一边测试一边写代码,确保代码的可靠性、确保效率,互相监督、互相学习,能从队友身上学到很多东西;

    结对编程的缺点:

    缺乏监督或者自觉可能会导致一人干活,一人休息;

    我的优点:

    在白天保证随叫随到、能全心全意编程、从队友身上学到了很多知识;

    我的缺点:

    缺乏设计思路,大多数时间跟随队友的思路;

    结对伙伴的优点:

    思路清晰、程序架构好、能解决难题

    结对伙伴的缺点:

    有时因为要完成其他作业没时间编程

    在你实现完程序之后,在附录提供的PSP表格记录下你在程序的各个模块上实际花费的时间。

    PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
    Planning 计划
    · Estimate · 估计这个任务需要多少时间 10 20
    Development 开发
    · Analysis · 需求分析 (包括学习新技术) 60 30
    · Design Spec · 生成设计文档 100 60
    · Design Review · 设计复审 (和同事审核设计文档) 30 30
    · Coding Standard · 代码规范 (为目前的开发制定合适的规范) 30 30
    · Design · 具体设计 200 300
    · Coding · 具体编码 400 600
    · Code Review · 代码复审 100 200
    · Test · 测试(自我测试,修改代码,提交修改) 100 200
    Reporting 报告
    · Test Report · 测试报告 30 30
    · Size Measurement · 计算工作量 30 20
    · Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 30 30
    合计 1120 1550
  • 相关阅读:
    mysql事务隔离级别回顾
    单链表倒数第K个节点的查找和显示
    mysql 行转列,对列的分组求和,对行求和
    获取分组后统计数量最多的纪录;limit用法;sql执行顺序
    You can't specify target table 'e' for update in FROM clause
    mysql 行转列 (结果集以坐标显示)
    springmvc执行流程 源码分析
    jdk动态代理 案例
    项目日志log管理
    apache和tomcat的区别
  • 原文地址:https://www.cnblogs.com/pyb1999/p/12560802.html
Copyright © 2011-2022 走看看