本博客是对结对编程队友郭冬妮同学的个人项目代码的分析和总结,郭同学用的是c++语言,我用的是java语言。虽然编程语言不同,但c++和java的类似性方便我们相互学习,也加深另一种编程语言的掌握,相互借鉴。
郭同学使用的是面向对象编程,文件分为三部分,层次分明
User.h
1 class User{ 2 private: 3 string Name;//用户名 4 string Password;//密码 5 string Type;//账号类型 6 int Quecount;//题目数量 7 ofstream out; 8 public: 9 void Sign();//登录函数 10 void Create_paperfolder();//生成用户文件夹函数 11 void Create_questions(int n);//生成题目函数 12 bool Check(string question,string Name); 13 void Change_type(); 14 };
在头文件中声明了User类,变量里设置了用户必须的属性:用户名,密码,账号类型。但是也申明了没必要的变量Quecount(题目数量)
不必要原因如下
申明函数:郭同学在将所有用户需要的函数封装载User中,从而使得main函数简洁。值得学习!函数具体内容在后面分析
User.cpp
郭同学在User.h中只写入函数声明,在User.cpp中对函数进行定义,使得代码较为清晰,值得我们的学习。
现在来分析每个函数的优缺或者是否优雅
1 while(true) { 2 cout<<"=====登录====="<<endl; 3 cin>>Name>>Password; 4 if(Name=="张三1"||Name=="张三2"||Name=="张三3") { 5 if(Password=="123") { 6 Type="小学"; 7 8 break; 9 } 10 } else if(Name=="李四1"||Name=="李四2"||Name=="李四3") { 11 if(Password=="123") { 12 Type="初中"; 13 14 break; 15 } 16 } else if(Name=="王五1"||Name=="王五2"||Name=="王五3") { 17 if(Password=="123") { 18 Type="高中"; 19 20 break; 21 } 22 } else { 23 cout<<"=====请输入正确的用户名、密码!====="<<endl; 24 cout<<endl; 25 } 26 } 27 cout<<endl; 28 cout<<"=====当前选择为"<<Type<<"出题====="<<endl; 29 cout<<endl; 30 Change_type(); 31 Create_paperfolder();
这段代码我一直觉得可以说是相当丑陋,不像是美丽漂亮的郭同学应该写出的代码(doge)。
用户的账号密码等信息应该是需要保存在本地,不然一但系统奔溃或者系统重启数据就会丢失。因此小声建议郭同学可以将用户数据放在本地,然后用文件流进行读取,在放到程序的数据结构中
2.登录之后没有类似于"请输入账号和密码的提示语",不具有用户亲和性
2.Create_paperfolder()和Check()
Create_paperfolder()
1 if(access(Name.c_str(), 0) != 0) { //创建用户名对应的文件夹 2 mkdir(Name.c_str()); 3 } 4 5 cout<<"=====准备生成"<<Type<<"数学题目====="<<endl; 6 cout<<"=====请输入生成题目数量(输入-1将退出当前用户,重新登录):"<<endl; 7 cin>>Quecount; 8 9 while(Quecount>30||Quecount<10) { 10 if(Quecount==-1) { 11 Sign(); 12 break; 13 } else { 14 cout<<"=====输入的题目数量无效,请重新输入:"<<endl; 15 cin>>Quecount; 16 } 17 } 18 19 char Filename[50]; 20 time_t It=time(NULL); 21 strftime(Filename, 50, "%Y-%m-%d-%H-%M-%S.txt", localtime(&It)); 22 string Path=Name+"\\"+Filename; 23 24 out.open(Path.c_str());//创建文件,以年月日格式命名 25 out<<"试卷科目:数学"<<"====="<<"难度:"<<Type<<"====="<<"题目数量:"<<Quecount<<endl; 26 27 Create_questions(Quecount);//题目生成函数 28 29 out.close();
Check()
1 bool User::Check(string question,string Name) { 2 string Checkpath=Name+"\\"+"Allquestion.txt"; 3 ifstream Checkin; 4 Checkin.open(Checkpath.c_str()); 5 string existquestion; 6 while(Checkin >> existquestion) { 7 if(existquestion==question) { 8 return false; 9 } 10 } 11 Checkin.close(); 12 13 ofstream Checkout; 14 Checkout.open(Checkpath.c_str(),ios::app); 15 Checkout<<question<<endl; 16 Checkout.close(); 17 18 return true; 19 }
这里得夸一下郭同学,
优点如下:
当然也有缺点,这个缺点也是我自己代码存在的,
1.我们的查重都是对所有题目进行直接遍历,当题目越来越多的时候,性能难免会受到影响。我之前想过将题目放进Hashmap中,题目这个String就作为Hashmap的key,从而查重的时候每个题目查重的复杂度变成了O(1),而且复杂度不会随着题目容量的变大而变大。希望后面和郭同学一起改进。
Create_questions() 这里是生成题目的函数,也是程序实现功能的部分,根据测试可以知道代码功能实现的很好。但明显的是代码可读性较差,因为不遵守Google代码规范造成的。也狠狠的提醒我了要好好遵守代码规范,不规范的代码真的dog都不看。建议郭同学好好阅读Google C++ Style。main.cpp
1 int main() { 2 User teacher; 3 teacher.Sign(); 4 return 0; 5 }
因为郭同学程序结构分明和包装性好,main函数简洁明了!
缺点
ToDO:建议郭同学查看自己的整个流程,查看哪里没有该循环的地方没有循环等等
该图输入回车后直接退出!
郭同学的代码采用了结构化和面向对象的思想,使得整体结构清晰易懂。但功能实现不完全,细节方面还有很多需要注意。例如代码规范和代码可读性,用户体验,引导性,以及程序优化性和可扩展性。这些都是郭同学在个人项目中表现不足的地方。在进行互评的时候我也去回想我的代码,有没有相同的问题,以及如何解决郭同学的问题。这些都给我带来了很多思考机会和体验。在之后的结对编程中,我也会和郭同学好好沟通,争取做出优秀的程序。