zoukankan      html  css  js  c++  java
  • 结对编程收获

    结对编程收获

      ——我和我的伙伴分到了Core组,他负责生成编写四则运算表达式函数,而我负责编写计算函数以及整体框架和接口

      这一次结对编程不仅学到了不少编程技术,更在交流合作中发现了自己以往的问题,因为我一直以来是一个偏爱独来独往的人,宁愿在合作中多干活,也不愿意别人对我的构想指手画脚,不过这一次是无法避免的了。

    编程收获


    1、实战经验

      这是一次难得的C++实战经验,或者说是一次面向对象语言的实践,C++更抽象一层的数据类型及其方法将我从以往繁重的体力活(用C语言编写)中解救出来,我也充分地利用了它不同于C的特性,将整个小项目的结构都编写得比较优美(至少是学习计算机语言以来)。(最后附上核心内部接口与外部接口)

    2、开发流程

    结队编程的效率=成员单独的效率-交流所带来的损耗,因此成员之间任务的耦合性越大,带来的损耗也越大,所以在合作的过程中,我有如下想法:

    1)前期:最好采用和-分-和的讨论方法。

      (1)和:成员需要全部参与到代码整体脉络的讨论当中,然后尽量地以减小任务耦合度为原则分配任务。

      (2)分:当两者(或者几个人)任务存在可能的交叉时,成员需要单独地进行交流,对设计的版块进行细致讨论。(这一阶段非常重要,只有细致地讨论、设计才有助于尽早地发现BUG,这对开发周期有百利而难有一害)

      (3)和:然而两者(或者几个人)交流完毕后,不能急匆匆地开始开发,需要重新召开组会,交流各个版块的设计思想,并至少需要一个统领全局的人明确整体的脉络,发现中间可能存在的冲突、重叠,然后提供改进的建议。

    2)开发:有几个需要注意的问题

      (1)如果数据结构存在重叠,即后者可能用到前者的数据结构时,那么他们的耦合度可以判定为高,需要共同设计代码、编写代码,并且开发时只有一人编写,而另一人需要实时观察、跟进。而两者(或者几个人)任务只是接口级别的,则可判定为低,需要事先约定好接口的类型,然后分别开发自己的模块,最后组建为一个类。

      (2)测试代码要跟进上每一个函数,尤其是项目越大这一点越是关键,虽然有一些函数因为参数表的问题难以编写测试类,然而并不能省略,因为之后的查错可能会把人逼疯。

    3)归并:需要在线(最好是面对面)的交流

      在各个同学便写完代码需要归并在一起的时候,可以按照树的结构逐步上提,当然每一个节点都是一个更高层次的功能来确定的。这时候需要进行面对面的联合测试,因为这样在对接的时候能充分化解歧义,并且前后调用函数的编写人可以互相交流容易忽视的点,可能出现的异常。

    3、开发周期:

      这次我充分吸收了上次个人编程时受到的教训,以逐次迭代的思想,我每开发一个新的模块时都列写出可能用到的最基本的函数,独立地进行编写、测试。事实上这样的经历是轻松+愉快的,在后期的调试中,至少没有在算法逻辑上遇到明显的问题。(当然C++这点没有Java做得好,Java的@Test注解对函数的测试是更加轻松的,也可能我学的C++太浅显了,毕竟从Java到C++的过渡只用了6个小时)

    4、开发感想:

      读了其他同学的收获,我感觉我上文所述的方案有些许遗憾,因为我太在意去除耦合性,让每个人去做独立的工作,却忽略了两个人一起编程(人数更多可能就不管用了)所带来的其他效益(这里的一起是指同时做一件事情)。因为两个人独立思考一种算法的时候能够发现更多的漏洞,这里我也有提到,也就是最初第一和第三步的公共讨论部分;另外互相监督能促使队友更高效地工作,而不是时不时就去看一眼其他无关的内容;最后还能减少debug的时间,领航员对驾驶员的代码大致了解的时候可能有不同于你的固有认识,我想这个方面的确可能是两个人合作的效率大于单干效率之和的。

    接口处理:


    1、前后接口讨论的重要性:

      诚如上文所言,在最初的讨论中所有成员都应该参加,但是这次并没有邀请UI组(甚至最开始的时候还没有考虑到要联系UI组,因为接口函数看上去已经确定了)。也如后来UI同学在群里抱怨的,虽然逻辑上各组之间差异不大,但是他们最初想得太美好了,接口参数表、返回值、甚至编写语言的不同让UI组的工作一下子重了不少。我们在之后的第二天找到了UI组的同学,不过他们讨论的积极性也不高,所谓的对接组内讨论也不了了之。

    2、人性化、例程:

      这一次我们的接口设计是比较成功的,因为据反馈有好几组UI都对我们的接口表示满意,我想这一方面得益于我在对接口设计时充分考虑到(a)尽可能少的调用函数完成尽可能多的事情(b)C语言仍然是所有同学熟练掌握的语言,并且它几乎成为各种编程语言会优先支持的外部语言;另一方面我也不厌其烦地在每一个版本中编写Test工程对dll进行测试,更对接口编写实际的使用例程并且不断进行更新,这样充分考虑用户感受使我们赢得了赞誉。

    代码展现:


     

    1、留给UI组的接口

    extern "C" __declspec(dllexport)
    void  SettingCal(int numOfOperand, int numOfQuestion, double rangeOfQuestion, bool addition, bool subtraction, bool multiplication, 
        bool division, bool power, bool brackets, int precision, bool properFraction, bool decimalFraction);
        
    extern "C" __declspec(dllexport) 
    void  GenerateAndCalc();
    
    extern "C" __declspec(dllexport) 
    const char*  getExpression(int count);
    
    extern "C" __declspec(dllexport)
    const char*  getAnswer(int count);
    
    extern "C" __declspec(dllexport)
    int numOfQuestion();
    View Code

    2、内部的代码框架

    struct ReversePolishType {
        stack<double> OPTR;        //操作数栈
        stack<char> OPND;        //操作符栈
    };
    
    struct fractionType {//假分数形式
        int    numerator;            //分子
        int denominator;        //分母
    };
    
    struct RPT_FractionType {//真分数的逆波兰式表示
        stack<fractionType> OPTR;
        stack<char>    OPND;
    };
    
    class OperationClass
    {
    private:
    //B同学:
        int numOfQuestion;        //题目的数量
        int numOfOperand;        //操作数的数量
        double rangeOfQuestion;    //题目中的数值范围
    
                                //运算符的种类
        bool addition;
        bool subtraction;
        bool multiplication;
        bool division;
        bool power;
        bool brackets;
        int precision;            //精度
        bool properFraction;    //是否支持真分数
        bool decimalFraction;    //是否支持小数
                                //都不支持说明支持整数
    //计算整形、小数形式的算式
        static ReversePolishType ReversePolishNotation(string Input)throw(...);                        //计算整形、小数形式的算式:根据string生成逆序波兰式
        static double CalReversePolishNotation(ReversePolishType expression)throw(...);                //计算整形、小数形式的算式:根据逆波兰式计算结果
    
    //计算分数形式的算式
        static RPT_FractionType RPN_FractionType(string Input)throw(...);                                //计算分数形式的算式:根据string生成逆序波兰式
        static fractionType CRPN_FractionType(RPT_FractionType expression)throw(...);                    //计算分数形式的算式:根据逆波兰式计算结果
                                                                                                                //分数形式的加、减、乘、除、乘方
        static fractionType fraAdd(fractionType a, fractionType b)throw(...);
        static fractionType fraSub(fractionType a, fractionType b)throw(...);
        static fractionType fraMul(fractionType a, fractionType b)throw(...);
        static fractionType fraDiv(fractionType a, fractionType b)throw(...);
        static fractionType fraPow(fractionType a, int b)throw(...);
    
    //A同学:
        string generate()throw(...);
        string generate1()throw(...);
        string generate2()throw(...);
        string generate3()throw(...);
        string generate0()throw(...);
    public:
        OperationClass();                //无参构造方法
    
    //提供给UI的属性、方法
    //对象的属性
        vector<string>    expression;        //存储生成的表达式
        vector<string>    answer;            //存储表达式的计算结果
        void Setting(int numOfOperand, int numOfQuestion, double rangeOfQuestion, bool addition, bool subtraction, bool multiplication, 
            bool division, bool power, bool brackets, int precision, bool properFraction, bool decimalFraction);/*设置属性:操作数数量,
        题目数量,数值范围,加法?减法?乘法?除法?乘方?(真分数?or小数?最后两项只可选其一,否则抛出异常)*/
        void GenerateAndCalc();
        void Generate();                //生成表达式,并存储在string当中
        void CalcAllExpression();        //对题目表达式依次进行计算,将结果string数组返回
                                        //获得对象的属性
        int getNumOfQuestion();            //获取题目数量设定值
    
    
    //B同学提供给A同学的方法
    //计算表达式expression
    //返回double类型的答案
        double CalcDouble(string expression)throw(...);                    //整数/小数形式表达式:对输入表达式字符串进行运算,然后以数值形式返回
        double CalcFrationDouble(string expression)throw(...);            //分数形式表达式:对输入表达式字符串进行运算,然后以数值形式返回
                                                                //返回string类型的答案
        string Calc(string expression)throw(...);                            //整数/小数形式表达式:对输入表达式字符串进行运算,然后以数值形式返回
        string CalcFration(string expression)throw(...);                    //分数形式表达式:对输入表达式字符串进行运算,然后以数值形式返回
    
    };
    View Code
  • 相关阅读:
    一种简洁明了的权限管理系统
    css小技巧(1)
    多功能旋转木马轮播实例
    jquery双向列表选择器select版
    jquery双向列表选择器DIV模拟版
    单击页面任何地方关闭隐藏层
    用户登录体验之密码框设计
    扁平化设计的美感
    分析网站的用户行为
    app的架构和导航设计
  • 原文地址:https://www.cnblogs.com/Trinidad/p/8893597.html
Copyright © 2011-2022 走看看