• 结对编程收获


    结对编程收获

     

    这次编程作业一路走来,学到了很多编程中实际很有用的东西,比如总体框架的设计,真的不能自己瞎想,应该到网上去查找相似的代码,先把别人代码的框架大致都看懂了,最好多看几份代码,比较一下几个框架的优点和缺点,然后在写代码之前规划好每个函数的输入输出,只有这样才算有点高年级同学写代码的样子。虽然在作业过程中,甲方的要求一直在改变,但是当你有了一个整体的框架感后,重构起来也能有全局感。

     

    总体架构的设计启发

    总体结构包括两个类,fomularNode和fomularCore,前者是表达式树的节点,包括必要的成员信息,后者是主要模块,public函数包括Calc Generate setting等主要函数。实现这些类的时候,对C++的public,private相关用法更加熟悉了。其实感觉现在C中的struct也可以这样写了。
    其实我现在是学习安全出身的,所以区分private和public的意义我还是很清楚的,但是感觉我们这次作业应该会没有那个黑客闲着回来攻击我们。。。所以个人想法还是尽可能地还是用public,这样使得高层类不会重复调用底层类的组合引发错误。最后再根据实际情况改为private。当然如果真正地去写一些应用的软件的时候,写的时候还是要以安全第一。

        class fomularNode
        {
        public:
            int value;
            bool chFlag;//if true,value is ascii
            fomularNode* lchild;
            fomularNode* rchild;
            fomularNode() :value(0),chFlag(false),lchild(NULL),rchild(NULL){}
            fomularNode(int val, bool flag, fomularNode* lch=NULL, fomularNode* rch=NULL)
            {
                value = val;
                chFlag = flag;
                lchild = lch;
                rchild = rch;
            }
        };
    
        class fomularCore
        {
        private:
            vector<fomularNode*> fomulars;
            vector<char> ops = {'+','-','*','/','^','(',')'};//all ops 需要保持最后两个是括号!
            vector<string> finalRes;//最终结果,和Generate返回值一一对应
            int maxopNum = 5;//每个表达式中运算符个数
            int range = 100;//操作数数的上限
            int precise = 2;//输出精度(最大为6)
            int fomuNum;//表达式个数
            int MaxRange = 100000;//运算中出现的最大数
            bool fractionflag = true;//是否进行分数运算
            double result[MAX_FOMU_NUM];//原始字符串运算结果
            bool okFlag[MAX_FOMU_NUM];//判断原始字符串是否符合要求
        public:
              //省略  
        }    
    
    
    
    实现的主要类函数包括:
    
    
        COREDLL_API string Calc(string inputFomu)
            {
                int multi;
                int tp;
                string tpFomu;
                long res;
                multi=findMultiple(inputFomu);
    
                if (fractionflag&&multi != 1&&!withDot(inputFomu))//有浮点'.'就认为不是分数运算
                {
                    tpFomu.append(to_string(multi));
                    tpFomu.append("*(");
                    tpFomu.append(inputFomu).push_back(')');
                    res = int(arthimetic(tpFomu));
                    tp = gcd(res, multi);
                    tpFomu = to_string(int(res/tp));
                    if(multi/tp!=1)
                        tpFomu.append("/").append(to_string(multi/tp));
                    return tpFomu;
                }
                else
                {
                    //这里似乎有概率访问越界
                    tpFomu=to_string(arthimetic(inputFomu));
                    for (int i = 0; i < 6 - precise; i++)
                        tpFomu.pop_back();
                    return tpFomu;
                }
            }
    
            COREDLL_API vector<string> Generate()
            {
    
                vector<string> rawFomu;
                vector<fomularNode*> judgedFomu;
                vector<string> finalFomu;
    
    
                rawFomu = geneExp(3*fomuNum);//3是可选参数,保证能选出符合要求个数的表达式
    
                toPostTree(rawFomu);//建树
                toJudgeTree();//判断是否符合要求
    
                for (size_t i = 0; i < fomulars.size(); i++)
                {
                    if (okFlag[i] == true)
                        judgedFomu.push_back(fomulars[i]);//选出合适的树
                }
    
    
                finalFomu=fomusToStr(judgedFomu);//树转表达式,去除多余括号
    
                for (size_t i = 0; i < finalFomu.size(); i++)
                {
                    //cout << finalFomu[i] << '=';
                    //cout << Calc(finalFomu[i]) << endl;//测试输出
                    finalRes.push_back(Calc(finalFomu[i]));
                }
    
                return finalFomu;
            }
    
            COREDLL_API vector<string> getRes()
            {
                return finalRes;
            }
    
            COREDLL_API bool settingXml(string path)
            {
                //xml方式setting
                string tpop;
                ReadXml(path, fomuNum, maxopNum, range, tpop, fractionflag, precise);
                for (size_t i = 0; i < ops.size(); i++)
                {
                    ops.push_back(tpop[i]);
                }
                return true;
            }
    
            COREDLL_API bool setting(int foN,int maxopN,int MaxR,string op,bool fraction,int preci)
            {
                //非xml方式的setting
                fomuNum = foN;
                maxopNum = maxopN;
                range = MaxR;
                ops.clear();
                for (size_t i = 0; i < op.size(); i++)
                {
                    ops.push_back(op[i]);
                }
                fractionflag = fraction;
                precise = preci;
                return true;
            }
    
     

    从bug收获的

    变量的取名真的很重要!!检查发现是判断二叉树是否相同的子函数的变量名写错了,左子树 lch 和右子树 rch 使用错误,再次阅读时也难以发现,说明一个好的变量名的重要性。

     

    界面模块,测试模块和核心模块的松耦合

    本次课程UI组和Core组的划分,让我对MVC原则理解更深刻了。具体来说,Core组主要负责程序核心(Model),UI 组的工作主要是用户交互(Controller)和数据显示(View)。当然,Core和UI组的功能划分也没有这么详细,具体情况具体分析,主要还是看编程者的思路。 具体对接的时候,有的UI组做的东西多,其实把core的一部分也做进来了,所以对接的时候还是很麻烦的。

     

    感觉xml真心好用

    这次xml读写部分是我写的,感觉xml读写方式真心好用,虽然最后貌似没有UI组用xml,大家都是通过函数接口直接通信的。但是涉及到不同的语言的交互,xml就能发挥它的威力了,比如我用C#写一个UI,用matlab写一个core,这个时候用xml就很方便了。而且相较于txt,xml应该不会受到编码方式以及其他各种格式的影响。

     

    我认为个人作业和结对编程的区别

    这次作业最大的收获就是明白了结对编程的意义,有一个好的队友真地很重要。在和队友结对编程的过程中,能看到对方的优点,同时看到自己的缺点,队伍里两个人由此都能得到巨大的进步。从开发层次来说,编写的代码同时经过2个人的眼睛,设计质量和代码质量都有了很大的提高,同时代码也更加规范了,因为谁也用不惯对方的代码风格,最后更多地偏向于书上提供的规范。同时,在这次结对编程中,认为马同学解决问题的能力很强,在难以描述的bug面前,总能在很短时间内解决问题,给我们的结对编程工作带来更大的信心以及更高的满足感。同时我们不断地编程过程,就是不断的复审过程,因为我们的一举一动都在对方的视线之内,在这种督促的压力下,我们的工作显得更加认真,并且我们要提高自己能力不让对方小看。结对编程使这次作业开发流程显得更加规范。

     

    走上工作岗位之后,是否会采用结对编程?

    走上工作岗位之后,很大概率不会采用结对编程。当然,培训新人的时候可能会考虑。因为结对编程特别适合于知识的分享和传递,特别适合于帮助开发者快速熟悉自己所不熟悉的领域。更多情况下是两个人水平相似,因此结对编程有浪费时间的嫌疑。另外结对编程的双方如果性格不合(这点概率是很大的),可能陷入很多的争吵,而导致进度停滞不前。而且结对要求结对的双方都要保证有充沛的精力,因为很容易疲劳。最后,结对编程不能完全替代代码评审,虽然结对编程对代码的审核程度比代码评审更加细致,但两个结对的人有一定的思维趋同性,从而忽略同样的问题。

     

    结对编程,教会我什么

    这两次作业给以后开发流程有很多可以借鉴的地方,其中个人感觉最重要的一点是要跑在时间前面,因为我(陈灿)第一次个人作业是在截至时间前一分钟提交的。把事情留在最后,的确能提高时间的效率,但是这是在拿自己project的质量冒险,因为在软件开发的过程中,可能会有各种各样的bug跳出来,而且在太大压力下编写的程序很大概率会有一些潜在的bug。在接下工程的那天开始,就得有一个详细的计划,规定XX天之前必须完成什么阶段。而且还要有足够的时间余量,来应对突发情况,这才是一个合格的程序员应该具备的素养。

  • 相关阅读:
    菜鸟学IT之四则运算升级版
    菜鸟学IT之简易四则运算程序开发
    菜鸟学IT分布式版本控制系统Git的安装与使用
    Javascript 编程范式
    【每日一题】2013年12月10日
    关于闭包的一些小东西
    【每日一题】2013年12月12日
    javascript学习计划
    新来挂号,以后就开始好好的维护这个博客了~
    【每日一题】2013年12月11日
  • 原文地址:https://www.cnblogs.com/moee/p/8893732.html
Copyright © 2020-2023  润新知