zoukankan      html  css  js  c++  java
  • 结对项目作业

    合作者:201631062114,201631062602

    代码地址:https://gitee.com/Changyu-Guo/pairing_project

    作业链接:http://www.cnblogs.com/guochangyu/p/9804719.html

    一、PSP表格

    PSP2.1

    PSP阶段

    预估耗时

    (分钟)

    实际耗时

    (分钟)

    Planning

    计划

    100

    120

    · Estimate

    · 估计这个任务需要多少时间

    100

    120

    Development

    开发

    1520

    1830

    · Analysis

    · 需求分析 (包括学习新技术)

    20

    15

    · Design Spec

    · 生成设计文档

    30

    35

    · Design Review

    · 设计复审 (和同事审核设计文档)

    20

    20

    · Coding Standard

    · 代码规范 (为目前的开发制定合适的规范)

    50

    60

    · Design

    · 具体设计

    100

    150

    · Coding

    · 具体编码

    1000

    约1300

    · Code Review

    · 代码复审

    200

    140

    · Test

    · 测试(自我测试,修改代码,提交修改)

    100

    110

    Reporting

    报告

    220

    250

    · Test Report

    · 测试报告

    100

    85

    · Size Measurement

    · 计算工作量

    20

    15

    · Postmortem & Process Improvement Plan

    · 事后总结, 并提出过程改进计划

    100

    150

     

    合计

    1840

    2200

     

    二、代码规范

      经过讨论,我们的项目主要是使用C/C++结合node.js进行开发,因此我们从网络上查找了相关的编码规范:

      C/C++:C/C++编码规范

      Node.js:JavaScript 风格指南/编码规范(Airbnb公司版)

    三、代码自审和互审

        制定了相关的代码规范后,就按照代码规范对自己的代码进行审查,由于自己很早之前就对代码规范进行过了解,因此在审查过程中并没有发现太多的问题。

        进行过代码自审过后,接下来就是代码互审,由于第一作业的代码比较简单,经双方商议后我们决定对命令处理模块、字符统计模块、单词统计模块、行数统计模块进行代码互审,过程中出现的问题如下:

    • 我的代码问题:代码在基本的风格比如缩进,变量命名上面并没有太大问题,主要就是代码的耦合性太高,各个功能模块代码相互关联,并且出现多个逻辑功能出现在同一函数里面的情况,不利于接下来的结对合作,需要对相应的模块进行抽离。 
    • partner代码问题:代码同样出现了耦合性过高的问题,其实就是变量及函数的命名有的不符合驼峰命名法,其他的都比较好(毕竟编译器自带代码格式化);

    四、设计过程

        经过双方的商讨和对原始代码的分析过后,并考虑到要使用图形界面,决定用node.js搭建一个后端服务器,如果命令里面存在-x选项,则启动服务器,并打开相应的页面,由用户发送ajax数据,后端接受后拼接成相应的字符串后,调用wc.exe并传入命令字符串即可得到结果,如果没有,则不用打开服务器和网页,直接调用wc.exe得到相应结果即可。代码的具体流程如下:

    wc模块的流程为:

     

    五、关键代码分析

    首先是node处理代码:

     1 // 判断是否存在-x选项
     2 if (process.argv.indexOf('-x') === -1) {
     3   // 如果不存在,就拼接命令字符串并执行
     4   process.argv.shift();
     5   process.argv.shift();
     6   process.argv.forEach(val => {
     7     cmdStr += ' ';
     8     cmdStr += val;
     9   });
    10   exec(cmdStr, function (err, stdout, stderr) {
    11     if (err) {
    12       console.log("执行错误,请检查命令是否合法");
    13       return;
    14     }
    15   });
    16 } else {
    17   // 如果存在-x指令,就启动服务器,并打开网页
    18   app.listen(3000, function () {
    19     console.log('app is running at port 3000.');
    20   });
    21   open('http://127.0.0.1:3000');
    22 }

        这段代码是入口程序代码,首先要做的是判断是否有-x指令,如果没有,就遍历指令数组,将指令拼接成字符串,然后调用C++程序并将字符串作为参数传进去。如果有-x指令,就启动服务器,并用浏览器打开网页。网页的效果如下:

    用户通过图形化的界面输入相关参数,然后后台获取数据后拼接成字符串,调用C++程序进行处理,后台代码如下:

     1 app.get('/', function (req, res) {
     2   res.type('html');
     3   res.render('index.html');
     4 });
     5 
     6 app.post('/data', function (req, res) {
     7   // 拼接选项
     8   for (var i = 0; i < req.body['options[]'].length; i++) {
     9     cmdStr += ' ';
    10     cmdStr += req.body['options[]'][i];
    11   }
    12   // 拼接输入文件
    13   cmdStr += ' ';
    14   cmdStr += req.body.filepath;
    15   cmdStr += ' ';
    16   cmdStr += '-o';
    17   cmdStr += ' ';
    18   cmdStr += path.dirname(req.body.filepath);
    19   cmdStr += '\';
    20   cmdStr += req.body.outfile;
    21   if (req.body.isStop !== '') {
    22     cmdStr += ' ';
    23     cmdStr += '-e';
    24     cmdStr += ' ';
    25     cmdStr += req.body.stopPath;
    26   }
    27   exec(__dirname + cmdStr, function (err, stdout, stderr) {
    28     cmdStr = '.\wc.exe';
    29     if (err) {
    30       console.log('err');
    31       return res.status(500).json({
    32         message: '服务器错误'
    33       });
    34     }
    35     return res.status(200).json({
    36       message: '成功'
    37     });
    38   });
    39 });

    C++程序主函数代码:

     1 int main(int argc, char *argv[]) {
     2     
     3     char commandStr[MAX_COM_LENGTH] = "";
     4     for(int i=1;i<argc;i++){        //将用户输入的指令拼接成一个完整的字符串传给程序 
     5         strcat(commandStr, argv[i]);
     6         strcat(commandStr, " ");
     7     }
     8 
     9     Command command;
    10     analyseCommand(commandStr, command);                    //解析用户指令 
    11     
    12     SourceFile *head = new SourceFile();
    13     if (command._s) getFileName(command.filePath, head);    //递归寻找目录下的文件 
    14     else {                                                //否则直接利用相对路径查找文件 
    15         SourceFile *p = new SourceFile();
    16         p->next = head->next;
    17         head->next = p;
    18         strcpy(p->fileName, command.filePath);
    19         strcpy(p->filePath, command.filePath);
    20     }
    21 
    22     wordCount(head, command.stopFile);                    //统计单词数 
    23 
    24     outPut(head, command);                                //结果输出到文件 
    25 
    26     delete head;
    27     return 0;
    28 }

        main函数是逻辑处理的核心,node程序调用C++程序后,首先进入main函数,然后main函数将传进来的参数拼接成字符串,将字符串传入相关函数进行解析,解析后会得到一个链表,这个链表存储了所有文件的相关信息,最后将链表传入统计函数和输出函数进行相应的处理。

    六、总结

        这是我人生中第一做结对项目,有很多收获,自己一个人写代码的时候,有很多考虑不周全的地方,但是有了partner的提醒和帮助,就能够设计出更加有逻辑和更加规范的代码结构,而且在编码的过程中,有很多问题比如某个功能不知道怎么写,但是和partner商讨过后就能很容易的解决。总体上来说,我觉得结对编程还是很大程度上提高了编码效率。

  • 相关阅读:
    Java并发包中Lock的实现原理
    多线程---再次认识volatile,Synchronize,lock
    共享锁(S锁)和排它锁(X锁)
    Java 7中的TransferQueue 以及 SynchronousQueue
    精巧好用的DelayQueue
    非阻塞同步算法与CAS(Compare and Swap)无锁算法
    彻底理解线索二叉树
    使用import取代require
    子页面iframe跨域执行父页面定义的JS方法
    利用js实现 禁用浏览器后退
  • 原文地址:https://www.cnblogs.com/guochangyu/p/9804719.html
Copyright © 2011-2022 走看看