结对编程——Peer代码解析
好的诗句源自反复的推敲,美的代码源自不断的review。
首先,回顾一下项目,我们大致回顾下代码需求:
-
完成一个算式题目的生成器,要求依靠账号登陆切换等功能。
-
题目有三种难度,分别为小学,初中,高中
-
小学题目为四则运算,初中至少包含一个开方或者平方,高中至少包含一个三角运算。
虽说这次的task主要是为各自的伙伴检查代码,但是“观其言而内自省也”,这个check的过程也应该是我们自己不断反思的过程。
首先,从最基础的代码规范开始。
写程序的一条准则是要解耦,这方面我觉得是大家有意识去做的一方面,效果也的确很好,我们都能够有意识地去分模块写代码,这样这个代码看起来就很公正有序。
1 void regis(); //用户登录 2 void get_g_testnum(); //确定题目数量 3 void qiehuan(string grade); //切换年级 4 void produce(); //产生题库 5 string getTime(); //文件名以时间命名
这样做带来的直观好处就是你的main函数看起来层次分明,不管是以后去调试还是什么都是很清楚:
1 int main() 2 { 3 srand(time(0)); 4 regis(); 5 get_g_testnum(); 6 produce(); 7 while(1) 8 { 9 cout<<endl<<"请输入要切换的年级或者qiut退出或输入‘切换用户’切换账号: "; 10 string order; //命令 11 string temp="切换"; 12 string ::size_type idx; 13 cin>>order; 14 idx = order.find(temp); 15 if(idx!=string::npos) 16 { 17 qiehuan(order); 18 produce(); 19 } 20 else if(!order.compare("qiut")) 21 exit(0); 22 } 23 return 0; 24 }
关于上面那些总的看来,命名言简意赅,读者也能望而知义,代码也能按模块区分,有利于之后的维护,但美中不足的是:
- 函数命名语言不能统一,中英文命名的互用让整体不是很和谐,最好应该统一为英文
- 函数命名可以更加详细,比如produce()可以换为produceQuesBank() 这样大家在阅读代码就知道这个一个产生题库的代码,不然后面突然看到这个produce没有注释就不知道是干嘛得了。
- 函数命名规范不统一,既采用了驼峰命名,又采用了下划线命名,也不利于代码的统一性
------------------------------------------------------------------------------------------------------------------这是一条分割线
之后,关于模块,融入我对需求的一些想法,也是许多人在写代码中做的不够好的部分:
所谓“分模块”,我们也不应该仅仅是分一个函数写在main类中就可以了,我们真正的分模块,应该是对将来功能可以延申的模块的单独封装。比如本题,我们起初要求只需要在dos界面输入密码账号,那么将来完全可能是UI界面,那么我们就可以将程度登录模块用类封装起来,之后只要用一个接口将题库产生与界面联系起来即可,嗯,这是基本的想法,大家也都有这个意识。
另外一方面,对于题目生成,我们设置了小学,初中和高中,我们该怎么去实现?是不是存在着某种继承关系在里面呢?
首先,我们可以确定,三个难度都存在着一个函数接口用来产生题目,我们所需要调用的其实只有这一种接口类型,那么我们是不是可以对三个难度进行封装然后实现一个统一的接口用来调用呢?那样就算之后再添加一个新的难度,我们也只需要新建一个类实现这个接口,其他部分都不用改动,是不是就很方便呢?这样之后我们只需要对UI界面提供一个统一的接口,在运行时根据类型时再确定是哪种题型就可以了。
说到这里,是不是又让人联系到了设计模式中工厂模式呢?我们是不是也可以把工厂模式应用到这个题型中呢·······可以优化的还有种种,虽然有的可能不必要,但也是锻炼了我们思维的方法!
-----------------------------------------------------------------------------------------------------------------这又是一条分割线
最后从功能具体实现上分析:
缺点1:对无意义括号的考虑
缺点2:对tan角度和根号等取值范围缺失判断
缺点3:初高中题目生成依赖于前一级题目生成,不能实现独立。
1 else if(g_grade=="初中") 2 { 3 for(int i=0;i<g_testnum;i++) 4 { 5 prod_xiaoxue(); //先生成小学的题目,再进行添加操作 6 prod_chuzhong(); 7 dataFile<<(i+1)<<": "<<g_test<<endl<<endl; 8 } 9 }
其中2,3两点也是我犯的问题,之后要寻找好的解决方法。
总的来说,大家都努力完成了项目,也是硕果累累,但是“A winner never stops his progress”,我们还要做的有许多,路漫漫兮其修远,吾将上下而求索。