项目 | 内容 |
---|---|
本次做业所属课程 | 2019BUAA软件工程 |
本次做业要求 | 结对编程做业 |
我在本课程的目标 | 完成该完成的任务,加强团队协做能力,熟悉软件开发 |
本次做业的帮助 | 切身体会结对编程,深刻了解其优缺点,增强与他人合做能力 |
项目地址html
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 10 | 10 |
· Estimate | · 估计这个任务须要多少时间 | 10 | 10 |
Development | 开发 | 1480 | 2430 |
· Analysis | · 需求分析 (包括学习新技术) | 200 | 360 |
· Design Spec | · 生成设计文档 | 60 | 60 |
· Design Review | · 设计复审 (和同事审核设计文档) | 20 | 10 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 20 | 20 |
· Design | · 具体设计 | 360 | 480 |
· Coding | · 具体编码 | 500 | 900 |
· Code Review | · 代码复审 | 120 | 240 |
· Test | · 测试(自我测试,修改代码,提交修改) | 200 | 360 |
Reporting | 报告 | 110 | 130 |
· Test Report | · 测试报告 | 60 | 60 |
· Size Measurement | · 计算工做量 | 20 | 10 |
· Postmortem & Process Improvement Plan | · 过后总结, 并提出过程改进计划 | 30 | 60 |
合计 | 1600 | 2570 |
即信息隐藏原则
David Parnas在1972年最先提出信息隐藏的观点。他在其论文中指出:代码模块应该采用定义良好的接口来封装,这些模块的内部结构应该是程序员的私有财产,外部是不可见的。
参照此原则,在本次项目中,诸如咱们的input类中的属性是私有的,全部的访问都是经过成员函数来实现。git
接口设计有六大原则,即单一职责原则、里式替换原则、依赖倒置原则、接口隔离原则、迪米特法则、开闭原则。本次项目的接口按照给定的要求实现,而且进行了封装,各个函数的功能也比较单一,接口的实现基本符合上述原则。程序员
松耦合,即函数功能尽可能单一,尽可能避免修改底层函数,功能相近的函数,能够设计两个以上,不要为了减小代码量,把一个函数的功能设计太多。github
本次项目中,每一个类都有相应的职责,如input类用于处理输入参数的处理,类的成员函数也有不一样的功能,提取参数,返回属性等。words类负责处理文件,提取单词。保证了每一个模块的功能独立性。算法
本次项目中计算模块用了面向对象类的方式进行封装。计算模块涉及到两个类,结点类Node和计算和接口在Core类中。经过Core的接口,传入接口规定的各种参数,构造单词相应结点对象,将结点对象存起来,对其进行拓补排序和动态规划计算。下面是几个函数的关系。编程
算法的关键在于怎么采用怎样的数据结构来存储数据。本次项目咱们用了26个vector来存储构造的结点对象,每一个vector中的结点对象都是相同字母开头的,并分别用一个二维数组和一位数组来存储结点间的边关系和相应字母开头的结点的入度。根据拓补排序再对26个vector进行排序,并用排好的序列进行动态规划求出最长链。对于有-r的状况,咱们决定用枚举的方式强行找出,可是还没来得及实现。数组
独到之处就在于用的数据结构不一样,这种存储方法能够节省内存,不用为每一个结点建一个相连的结点vector,而且使用二维数组表示两类结点的边关系更能容易判断出有没有环。数据结构
以前用的是每一个结点有一个vector来存储与其相连的结点的形式来实现接口,这样拓补排序的实现会相对较慢,采用上面第4点的结构进行接口实现的优化以后,性能获得了改进,下面是改进以后的效能分析图:函数
Design by Contract即契约编程,是设计软件的一种方法。它规定软件设计者应为软件组件定义正式,精确和可验证的接口规范,这些规范扩展了具备前置条件,后置条件和不变量的抽象数据类型的普通定义。而Code Contract规定了接口的数据类型,接口执行以前的条件和接口执行以后的条件。oop
我认为契约编程的好处是在于因为契约的存在,至关于给代码进行了严格的约束,必定程度上保证了代码的功能。相对的缺点是比较繁琐,增长工做量。
本次项目并未严格按照契约式编程规定前置条件,后置条件以及不变量,咱们是按照给定的接口格式和文件格式来实现
计算模块的单元测试覆盖率达到了93%,以下图所示:
单元测试测试了正常状况(前两个)和异常状况(后一个)。第一个测试的是get_chain_word的状况,第二个测试的是get_chain_char的状况,异常状况测试了不存在-r参数时输入有环的异常状况。以下:
没有-r参数时有环的异常状况;设计目标是发现输入中没有-r参数进行“输入文件中存在环”的提示并退出程序。
对于输入文件不存在的异常状况;设计目标是给出提示“Error opening file",并结束程序。
对于输入中诸如同时出现-w -c的异常状况,设计目标是给出提示“para error",并结束程序。
咱们只实现了命令行模块。
本次项目专门设计了一个Input类来实现命令行输入地处理,其中类中的属性有is_w、is_c、is_r、filePath等,都是私有属性,必须经过相应的成员函数访问。主要用类中的spilt方法来分割各个参数。
spilt方法根据传入的命令行参数,辨识出具体是那个参数,而且出现一次后进行标记,相同参数再出现则报错,-w -c亦是如此。提取出相应参数后给相应属性赋值。
咱们将计算模块暴露出来两个接口,命令行在处理完并构造出单词表以后可使用这两个接口和计算模块进行链接。
static int gen_chain_word(char* words[], int len, char* result[], char head, char tail, bool enable_loop); // 计算最多单词数量 static int gen_chain_char(char* words[], int len, char* result[], char head, char tail, bool enable_loop); // 计算最多字母数量
驾驶员和领航员,一个在写代码,一个在旁边看
结对编程的好处
1. 多双眼睛,少点 bug:两人互相监督工做,能够加强代码和产品质量,并有效的减小 BUG
2. 互相学习编程技巧:在编程中,相互讨论,能够更快更有效地解决问题,互相请教对方,能够获得能力上的互补
3. 互相监督,不容易偷懒:两我的一块儿工做须要互相配合,若是想偷懒去干别的,就会拖延工做进度
结对编程的坏处
1. 开发人员可能会在工做时交谈一些与工做无关的事,分散注意力,形成效率低下
2. 须要高强度下编程时效率会低
成员的优缺点
成员 | 优势 | 缺点 |
---|---|---|
曾林思 | 工做积极、 对算法进行改进、 更好地提出思路 | 不够细心 |
张峻槐 | 细心、 对搭档友好、 能提出不少好建议 | 对算法不敏感 |
见第2条