结对编程初体验——代码复审

这一次和室友结对编程,第一项任务就是互看代码。想到上一次这样认真看她的C++代码,是一年前学程序设计这门课时,帮她人工debug。虽然都是从头到尾认真读代码、通逻辑,感觉却是不同的,之前的关注点是bug在哪,而现在却是带着任务的,要关注代码核查表中的项目。结果看着看着,总感觉自己在找茬dbq

回归正题↓



编译环境:Dev-C++ 5.9.2

程序语言:C++


(一)优点:

能发现的优点,大多都是自己的缺点

1、代码可读性强。

通过详细的注释,即便是我们两个的个人项目使用的不是同一种语言,我看懂她的代码并没有花费很多时间。在她的代码中,几乎每一句关键语句上都加了注释,说明其功能,通过看注释,其实就可以基本明白所有需求实现的逻辑了。也不出我所料,她在看我的代码的时候非常绝望。因为过去编程都是个人编程,还没有过组队做项目的经历,所以我习惯只在程序块和变量定义前面加注释,标记数据块的功能和实现逻辑。这样虽然自己复查或者修改代码时可以看懂,但却给其他看代码的人带来了极大的麻烦。

2、基本符合高内聚、低耦合原则。

每一个功能都封装成了一个函数,只有在主函数中,按照流程依次调用了各个功能函数,其余函数之间几乎没有相互调用,基本做到了模块与模块之间,尽可能的独立存在。这一点也是我的代码做的不太好的一点,为了开发时省事,我将功能划分的比较大,每个实现子功能的函数都相对复杂,这样一来,一旦某一个小功能需求改变,就需要在一个大模块中调整,工作量会增大、出错率也会提高。

3、巧妙使用了容器。

看到她的代码开始定义的几个容器,给了我很大启发。容器的简单性、轻量性、可扩展性、可移植性的优点突然出现在脑子里,感觉自己用的数组特别low。(不过仔细看过后,这里使用容器还是有问题的,这个在后面的缺点里说吧)不管怎么样,这个项目还是有很多地方可以用容器呀。

4、可以自动创建用户文件夹。

需求中说,“每个账号一个文件夹”,我当时是按照用户文件夹提前创建好,然后生成试卷后寻址,存入该文件夹来理解的。而她的代码思路我觉得更好,在准备生成第一套试卷时,若用户文件夹不存在,则创建,这样一来扩展性比较强,当用户增多,或者需求改成用户表不是预设好的,而是通过注册产生的时,就会容易实现得多。

5、代码风格相对规范

括号的位置、函数和变量的命名,都较为规范。

(二)缺点

由于代码复审的思想,发现的不足和bug会多一点,下面开始疯狂diss

1、注释不是很规范。

注释多,是优点,也是缺点。例如函数的注释,放在函数名和前括号"{"之间,有些影响美观。

 1 int GetLevel(string name) //用于判断当前用户姓名并且确定用户身份等级,选择出题对象
 2 {
 3     if ((name.compare("张三1") == 0) || (name.compare("张三2") == 0) || (name.compare("张三3") == 0))
 4     {
 5         cout << "当前选择为小学出题" << endl;
 6         return 1; //小学老师表示为1
 7     }
 8     else if ((name.compare("李四1") == 0) || (name.compare("李四2") == 0) || (name.compare("李四3") == 0))
 9     {
10         cout << "当前选择为初中出题" << endl;
11         return 2; //初中老师表示为2
12     }
13     else if ((name.compare("王五1") == 0) || (name.compare("王五2") == 0) || (name.compare("王五3") == 0))
14     {
15         cout << "当前选择为高中出题" << endl;
16         return 3; //高中老师表示为3
17     }
18 }

2、容器使用不恰当,导致不能达到需求。

仔细阅读代码后,发现她定义的几个容器的作用是存储当前用户在本次程序所生成的所有试题,用于查重。而需求中的查重指的是题目不能与该用户文件夹下所有文件中试题重复。因此需求没有真正实现。

3、to_string函数实现不够机智。

int型转换成string型,完全可以调用库函数,或者用String str = i + "";这样一条语句完成,无需定义这么复杂的函数按位转换哟。

 1 string to_string(int n) //定义将整型转换为字符串的函数n
 2 {
 3     int m = n;
 4     int i = 0, j = 0;
 5     char s[100];
 6     string astring;
 7     while (m > 0)
 8     {
 9         s[i] = m % 10 + ‘0‘;
10         m /= 10;
11         i++;
12     }
13     s[i] = ‘\0‘;
14
15     i = i - 1;
16     while (i >= 0)
17     {
18         astring += s[i];
19         i--;
20     }
21     astring += ‘\0‘;
22
23     return astring;
24 }

4、加括号策略伪随机。

加括号策略不能实现某两个操作数之间有两个或两个以上括号的情况。

 1 void AddBracker(int i, char m[], char n[]) //加括号
 2 {
 3     int a[i];
 4     memset(a, 0, sizeof(a));
 5     int bracker_num = random(1, i);
 6     while (bracker_num > 0)
 7     {
 8         int t = random(1, i);
 9         if (a[t - 1] == 0)
10         {
11             a[t - 1] = 1;
12             int tem = random(t, i);
13             if (a[tem - 1] == 0)
14                 a[tem - 1] = 2;
15             else
16                 a[t - 1] = 0;
17
18         }
19         bracker_num--;
20     }
21
22     for (int k = 0; k < i - 1; k++)
23     {
24         if (a[k] == 1 && a[k + 1] == 2)
25         {
26             a[k] = 0;
27             a[k + 1] = 0;
28         }
29     }
30     for (int k = 0; k < i; k++)
31     {
32         if (a[k] == 1)
33             m[k] = ‘(‘;
34         if (a[k] == 2)
35             n[k] = ‘)‘;
36     }
37 }

5、初、高中运算符策略伪随机。

初中的平方和开根号、高中的sin、cos、tan运算符,在两个操作数之间都不能有多个同类运算符。比如“tan(cos15)”这样的式子就无法生成。

 1    if (m[0] == ‘(‘ && n[i - 1] == ‘)‘ && (a[i - 1].compare("^2") != 0 || a[i - 1].compare("^1/2") != 0)) //如果首尾都是括号且没有整体平方或开根操作
 2     {
 3         m[0] = ‘\0‘;
 4         n[i - 1] = ‘\0‘;
 5     }
 6
 7     for (int j = 0; j < i; j++)
 8     {
 9         equation += m[j];
10         equation += to_string(CreatOperator());
11         int jud = random(0, 1);//判断平方或者开根操作是在括号前还是括号后的
12         if (jud == 0) //如果判断结果为0 则平方或者开根操作在括号内
13         {
14             equation += a[j];
15             equation += n[j];
16         }
17         if (jud == 1)//如果判断结果为1 则平方或者开根操作在括号外
18         {
19             equation += n[j];
20             equation += a[j];
21         }
22         if (j != i - 1)
23             equation += CreatSymbol();
24     }

6、用户登录方式扩展性低。

判断用户是否成功登录的逻辑,室友是采用if-else暴力判断的,这样一来,当用户多起来,或者需求变为用户表由注册产生时,就无法扩展实现了。这也让我发现,我的方式也有同样的问题,我是将账号密码分别存入两个数组。由此我想到了更好的解决方式,使用类来封装,将用户信息封装到用户类中,这样当注册信息增添了其他内容时,也可以轻松扩展。

7、代码冗余多。

但看判断用户类型这一循环,在很多函数中都用到了,if-else多重判断,好多子功能函数中都重复了这一段代码。就当前实现来看,我觉得可以把这一过程写成函数或者宏定义,避免多次重写,修改的时候也需要多处同时改。更好的解决方式同6中提到的,如果用户信息封装成类,用户类型即可作为类中一个成员变量。

8、没有合理预测未来需求。

这样一个功能,因为要面向用户,做UI是大势所趋,所以第一版如果直接写成界面,而不用命令框,结对项目就可以不用重写了,所以本次结对项目应该是要以我的JAVA项目为底层代码,进行修改了。

9、切换出题类型的需求实现不够人性化。

用户只有在刚登录时可以切换出题类型,之后就只能在当前类型下多次出题,要想换类型只能重新登录。这一点极大影响了用户体验。

(三)感想

1、开始结对编程前让我们互看代码,非常有意义。一方面对方可以帮忙找到自己的bug或者不足,通过看对方代码,无论是对方的优点和缺点,总能联系到自己,发现自己可以改进的地方。

2、代码复审的重要原则——沟通。在看代码的过程中,我和结对编程的队友因为是室友,所以有足够的时间互相提问,有时候研究好久的几行代码,通过开发人员的一句话,就都懂了。

3、写博客的好处,通过这篇博客,可以记录我们互看代码发现的问题,和要改进的点,不至于在过两天开工结对编程项目时,把这些都忘干净了。

原文地址:https://www.cnblogs.com/gifted35/p/9715514.html

时间: 2024-10-10 10:58:35

结对编程初体验——代码复审的相关文章

Shell脚本编程初体验

Shell脚本编程初体验 分类 编程技术 通 常,当人们提到"shell脚本语言"时,浮现在他们脑海中是bash,ksh,sh或者其它相类似的linux/unix脚本语言.脚本语言是与计算机 交流的另外一种途径.使用图形化窗口界面(不管是windows还是linux都无所谓)用户可以移动鼠标并点击各种对象,比如按钮.列表.选框等等.但 这种方式在每次用户想要计算机/服务器完成相同任务时(比如说批量转换照片,或者下载新的电影.mp3等)却是十分不方便.要想让所有这些事情变得简单并 且自动

bash编程初体验之for

bash编程初体验之for for while until 概述 本文将介绍以for为代表的循环语句在shell 脚本中的应用,常见的循环语句有for, while, until,作为循环语句,顾名思义,它就是重复地做一件事,直到满足某一条件而退出:另外,还有两个循环控制语句continue与break来配合循环语句,以实现临时中断或跳出循环的功能:以下为for, while, until的知识点提炼: for, while, until 进入条件          for: 列表元素非空   

bash编程初体验(二)

bash编程初体验(二) read if case 概述 在本篇文章中,我们将介绍bash编程中有关if语句的简单用法,.如此,如果条件为真,if会执行一种指令,如果条件为假,if会选择执行另一种指令,这种执行就是所谓的选择结构,它能够改变命令的基本顺序流结构,以选择流的形式运行. 在有关if语句的论述中,我们还将介绍read命令,因为read命令可以方便地引入一个或多个变量,可以天然地与if语句结合:另外,除了if语句,还有一种常见的选择语句:case语句,其简单易用,高效简洁,是时的不二选择

WMI脚本编程初体验

1.简介 WMI是Windows 的管理支持技术,WMI最初于 1998 年作为一个附加组件与 Windows NT 4.0 Service Pack 4 一起发行,是内置在 Windows 2000.Windows XP 和 Windows Server 2003 系列操作系统中核心的管理支持技术. WMI 是一种规范和基础结构,通过它可以访问.配置.管理和监视所有的 — 几乎所有的 Windows 资源. 2.WMI脚本编程初体验 先看一个例子:使用 WMI 和 VBScript 检索总物理

结对编程初涉猎——结对伙伴的代码复审

至此为止,个人作业阶段就结束了,从此便进入团队合作阶段.这次是先从结对编程开始,虽然还没有进入正式的开发状态,但也是结对编程的小开端,同时也是一个复习代码复审这部分内容的过程. 阅读目录 1.题目要求 2.结对体验 3.代码审查表 4.队友代码及优缺点评价 5.个人感想 题目要求 要求: (1). 首先在同学中找一个同伴,范围不限,可以在1~5班中随意组合,建议尽量不要找同组的成员,女同学尽量找男同学结对,但是不做强制要求: (2). 从以往个人完成的项目中选择一个作品,例如:以往的数据结构课程

结对编程——初读队友代码

队友的个人项目是在pycharm环境下用python写的,共分为三个模块:Users;fouroperate:GUIapp,他们的功能分别如下: GUIapp:主控制台模块,控制用户输入密码修改等级,输入信息等,加入了界面,可生成exe文件(这点真的超级棒,似乎花了队友大量的时间进行额外的学习,这点值得我学习). Users:用户信息模块,存储用户名.密码状态等. fouroperate:控制表达式产生的模块. 代码优点分析: 1.注释清晰,在每个代码模块前.每个类.函数之前都有注释说明该模块的

结对编程:队友代码分析

按照结对编程要求,对队友的代码进行分析.在代码中发现的问题可以提醒队友或者警示自己. 优点: 一.代码以外: 1.使用语言为Python,比起JAVA和C++方便许多,而且实现许多功能也方便许多,可以说是从开始就为拓展打好了基础.事实上也的确因为这点,我们选用了他的代码作为核心 2.文件按功能分为几个文件,命名为CreatSymbol.CreatFirst.CreatSecond.CreatThird.Test.各个函数位置明确,命名规范 3.注释详细且明确.文件/函数的开头都有注释,各关键部分

对二分法的学习体会以及关于结对编程的体验分享

1) 二分搜索技术 二分搜索算法是运用分治策略的典型例子.二分搜索方法充分利用了元素间的次序关系,采用分治策略,可在最坏的情况下用O(logn)时间完成搜索任务. 问题描述:给定已排好序的n个元素a[0: n-1],现要在这n个元素中找出特定的元素x. 解决方法: a) 顺序搜索方法:逐个比较a[0: n-1]中元素,直至找出元素或搜索整个数组后确定x不在其中.该方法没有很好地利用n个元素已排好序这个条件,因此在最坏的情况下,顺序搜索方法需要O(n) 次比较. b) 二分搜索方法:将n个元素分成

从结对编程初项目窥团队合作编程

一.  前言: 本次项目要求在个人项目的基础上,两人结对合作,对原有代码进行合作. 在上次的个人项目中,我的队友选择了Python进行开发,而我选择了Java:经过沟通后,这次的结对项目我们选择以Java版本的代码为基础,优化代码,添加模块. 二.  项目介绍: 项目名称: 带UI的小初高数学学习软件   2. 用户: 小学.初中和高中学生 3.功能: a.用户登陆注册功能和密码管理功能: 1)用户提供手机号码,点击注册将收到一个注册码,用户可使用该注册码完成注册; 2)用户完成注册后,界面提示