结对项目:最长单词链

1.Github项目地址:

Wordlist

2.PSP表格及预估开发时间:

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

3.教程与设计:

  • Information Hiding,即信息隐藏,类似于大二面向对象编程中的代码封装。和授课老师常说的 “你要什么告诉我,我拿给你” ,区别于将口袋里的东西直接展示给使用者,封装后的代码隐藏实现需求的具体步骤,留下接口给使用者调用,或者类的方法的调用。在本次作业中,我们将计算部分的核心代码封装为一个Core类,并分离出来,为它配置了数个接口,让外界调用来获得期望的数据,但不对外暴露实现的具体方法,隐藏了代码的运行过程和信息。
  • Interface Design,即接口设计,既是一种好的习惯也是一个非常重要的手段。通过将一个类集合成一个或几个特定的接口,使用户对于程序的使用通过接口来进行,符合面型对象的思想,同时也便于维护和扩展。本次作业里要求的两个接口nt gen_chain_word(char* words[], int len, char* result[], char head, char tail, bool enable_loop)和int gen_chain_char(char* words[], int len, char* result[], char head, char tail, bool enable_loop)就很直观的体现了单词链程序本身的特点,也便于测试。
  • Loose Coupling,即松耦合,是指程序的不同功能之间耦合度较低,不互相依赖,任何一个功能的使用和修改对其他的功能影响不大。在本次作业中,要求将核心计算过程封装为Core单独分离出来,并产生dll文件,可以通过命令行来进行测试和调用。

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

  • 深度优先算法(DFS)和拓扑排序、动态规划。将有长度的单词看做带权的有向边,通过将入度为零的节点(单词的首位字母)不断去掉,减少26*26的有向图中的点,得到一个拓扑序列,再按照得到的序列向最后一个(被指向最多的尾字母)延伸,记录途中的信息,就能得到“最长路径”(“-c”)。其他要求基本可以从该方法演变(“-w”可视为“-c”中边长度全为一,“-h”,“-t”即对最长路径的截取)而来。

5.UML:

6.计算模块接口部分的性能改进:

  • 一开始独立设计时采用了DFS,用近乎暴力枚举的方式写了一个最长路径的算法,结果在跑测试数据时久久不能输出结果,思考后发现性能基本消耗在递归的过程中。于是采用了拓扑排序的方法,避免递归,并在尽量少的遍历次数下完成排序和路径的生成。再完成后面对一万左右的单词量就可以用几秒算出结果了。

7.Design by Contract:

  • 契约式设计(编程)要求软件设计者为软件组件定义正式的,精确的并且可验证的接口,这样,为传统的抽象数据类型又增加了先验条件、后验条件和不变式。
  • 契约式设计规定了一个程序模块确定的接口,让程序设计更精确,在多人共同开发时不会互相影响产生混乱。在结对编程中保证了设计接口时具备先验条件、后验条件和不变条件,能互相配合。

8.计算模块部分异常处理说明:

void judge() {
	if (wflag == 1 && cflag != 1 && rflag != 1) {
		wchain();
	}
	else if (wflag != 1 && cflag == 1 && rflag != 1) {
		cchain();
	}
	else if (wflag == 1 && cflag == 1 && rflag != 1) {
		cout << "ERROR, -w and -c can not be both requested!" << endl;
	}
	else if (rflag == 1) {
		rchain();
	}
}
  • 不允许-w和-c两种方法同时使用。
if ((fopen_s(&fp, cpath, "r")) != 0) {
		printf("file not exist\n");
	}
  • 对错误路径异常的输出。

9.界面模块与计算模块的对接:

for (int ar = 1; ar < argv; ar++) {
		if (argc[ar][0] == '-') {
			if (argc[ar][1] == 'w') {
				wflag = 1;
				if (argc[ar + 1][0] != '-') {
					strcpy_s(cpath, argc[ar + 1]);
				}
			}
			else if (argc[ar][1] == 'c') {
				cflag = 1;
				if (argc[ar + 1][0] != '-') {
					strcpy_s(cpath, argc[ar + 1]);
				}
			}
			else if (argc[ar][1] == 'r') {
				rflag = 1;
			}
			else if (argc[ar][1] == 't') {
				tflag = 1;
				top = argc[ar + 1][0];
			}
			else if (argc[ar][1] == 'h') {
				hflag = 1;
				hop = argc[ar + 1][0];
			}
		}
	}

在读入参数之后,进行命令行参数的处理,判断参数的正确性,并根据参数来分别调用Core模块中的接口进行计算。

10.结对过程:

11.结对编程及其优缺点:

结对编程:

  • 优点:两人结对配合,能力有所互补,互相督促和帮助。
    便于讨论问题,能在编程的同时交流想法,快速解决问题。
  • 缺点:个人习惯不同,时间也难以统一,有时会带来一些麻烦。

个人优缺点:

  • 优点:抗压能力较强,学习积极性较高,热心学习对方的长处。
  • 缺点:个人能力薄弱。

结对同学优缺点:

  • 优点:个人能力强,执行力强,项目进展推进快。
  • 缺点:比较专心,交流较少。
posted @ 2019-03-14 23:21  贰仟  阅读(199)  评论(4编辑  收藏  举报