zoukankan      html  css  js  c++  java
  • 附加作业 软件工程原则的应用实例分析

    作业要求参照:[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2446]

      随着完成作业的增多,软件工程的原则也逐渐体现在作业代码里了,一些以前的坏习惯也在逐步纠正。让我印象比较深刻的是代码的重复利用这一块。这儿举两个作业进行对比,一个是词频统计,另一个是四则运算。

      git地址如下:词频统计:https://git.coding.net/shishishaonian/word_count.githttps://git.coding.net/shishishaonian/word_count.githttps://git.coding.net/shishishaonian/word_count.githttps://git.coding.net/shishishaonian/word_count.git

                 四则运算:https://git.coding.net/shishishaonian/four_arithmetic_operation.git

      在词频统计代码中,我并没有考虑到代码的重复利用,对每一个题目要求都编写一个统计函数,最后整个代码很长,main函数写了接近300行,阅读起来很困难。部分代码如下:

    int main(int argc, char** argv) {
        if (argc == 3) {
            FILE *fp = NULL;
            fp = fopen(argv[2], "r");
            char ch = fgetc(fp);
            int len = 0;
            long totalword = 0;
            string str = "";
            map<string, int>mp;
            vector<string>s;
            vector<pair<string, int> >pa;
            while (ch != EOF) {
                        ...//统计单词函数
                    }
                    ...//统计词频函数
            return 0;
        }
        if (argc == 2) {
            if (strcmp(argv[1], "-s") == 0) {
                char ch;
                int len = 0;
                long totalword = 0;
                string str = "";
                map<string, int>mp;
                vector<string>s;
                vector<pair<string, int> >pa;
                while ((ch = getchar()) != EOF) {
                       ...//统计单词函数
                            }
                            ...//统计词频函数
                return 0;
            }
            else {
                char buf[80];
                char *myFileBasePath =getcwd(buf, sizeof(buf));
                strcat(buf, "\");
                strcat(buf, argv[1]);
                int judgeDirResultCode = is_dir_exist(myFileBasePath);
                if (judgeDirResultCode == 0) {   
                    _finddata_t sfind;
                    strcat(buf, "\*.txt");
                    long lresult = _findfirst(buf, &sfind);
                    do { 
                        string path = sfind.name;
                        path += '';
                        FILE *fp = NULL;
                        fp = fopen(path.c_str(), "r");
                        for (int i = 0; i<path.length() - 5; i++) {
                            printf("%c", path[i]);
                        }
                        printf("
    ");
                        char ch = fgetc(fp);
                        int len = 0;
                        long totalword = 0;
                        string str = "";
                        map<string, int>mp;
                        vector<string>s;
                        vector<pair<string, int> >pa;
                        while (ch != EOF) {
                              ...//统计单词函数
                                            }
                                            ...//统计词频函数
                                    }while (_findnext(lresult, &sfind) == 0);
                    return 0;
                }
                strcat(argv[1], ".txt");
                FILE *fp = NULL;
                fp = fopen(argv[1], "r");
                if (fp == NULL) {
                    printf("该文件/文件夹不存在!
    ");
                    return 0;
                }
                else {
                    char ch = fgetc(fp);
                    int len = 0;
                    long totalword = 0;
                    string str = "";
                    map<string, int>mp;
                    vector<string>s;
                    vector<pair<string, int> >pa;
                    while (ch != EOF) {
                                ...//统计单词函数
                                    }
                                    ...//统计词频函数
                     return 0;
                }
            }
        }
        if (argc == 1) {
            char ch;
            int len = 0;
            long totalword = 0;
            string str = "";
            map<string, int>mp;
            vector<string>s;
            vector<pair<string, int> >pa;
            while ((ch = getchar()) != '
    ') {
                  ...//统计单词函数
                    }
                    ...//统计词频函数
            return 0;
        }
    }                                                
    View Code

      这部分代码中,单词统计和词频统计部分的代码是一模一样的,我是把这两个函数在主函数中写了五遍,搞得整个代码又臭又长。如果将两个功能函数在主函数外写成单独的函数,主函数中进行调用,就可以简化很多行代码,使整个代码更加利于阅读。

      在四则运算中,我吸取了之前的教训,把功能函数写在了主函数之外,在需要的时候就直接进行调用。部分代码如下:

    void CreateEquation(vector<char>&ve)
    {
        ...
    }
    void RPNotation(vector<char>&st,vector<char>ve)
    {
        ...
    }
    void Correct_Ans(vector<char>st,double &correctAns)
    {
        ...
    }
    void PrintfEquation(vector<char>ve)
    {
        ...
    }
    bool Is_Equal(double a,double b)
    {
        ...
    }
    int main(int argc,char** argv)
    {
            srand(time(NULL));
        if(argc==1)
        {
            int rightnum=0;
            for(int i=0;i<20;i++)
            {
                CreateEquation(vec);
                RPNotation(st,vec);
                Correct_Ans(st,correctAns);
                PrintfEquation(vec);
                printf("
    ?");
                double t;
                scanf("%lf",&t);
                if(Is_Equal(correctAns,t))
                {
                    rightnum++;
                    printf("答对啦,你真是个天才!
    ");
                }
                else
                {
                    printf("再想想吧,答案似乎是%g喔!
    ",correctAns);
                }
            }
            printf("你一共答对%d道题,共20道题。",rightnum);
            return 0;
        }
        if(argc==3)
        {
            string str=argv[2];
            for(int i=0;i<str.length();i++)
            {
                if(str[i]>='0'&&str[i]<='9')
                {
                    continue;
                }
                printf("题目数量必须是 正整数。");
                return 0;
            }
            int a=atoi(str.c_str());
            if(a<=0)
            {
                printf("题目数量必须是 正整数。");
                return 0;
            }
            int rightnum=0,totalnum=atoi(argv[2]);
            FILE *fp=fopen("题目.txt","w");
            for(int i=0;i<totalnum;i++)
            {
                CreateEquation(vec);
                RPNotation(st,vec);
                Correct_Ans(st,correctAns);
                int j;
                for(j=0;j<vec.size();j++)
                {
                    printf("%c",vec[j]);
                    fprintf(fp,"%c",vec[j]);
                }
                for(;j<50;j++)
                {
                    printf(" ");
                    fprintf(fp,"%c",32);
                }
                Fraction f1=(correctAns);
                f1.Print();
                //printf("%g
    ",correctAns);
                //fprintf(fp,"%g
    ",correctAns);
            }
            return 0;
        }
    }
    View Code

      这样通过调用外部函数的形式,使整个代码简化了不少,阅读起来也舒服方便了很多。

      软件工程中的原则仅仅应用在一两次的作业中可能感觉不到明显优势,但如果应用在长期的代码实践中就会使人直观地感受到它带来的方便与实用。不仅仅可以统一代码风格,还可以提高代码编写速度、方便代码修改、提高阅读体验等。在以后的软件开发中,我们应该善于使用软件工程原则,更加合理简便地进行软件开发。

  • 相关阅读:
    【转载】 下载百度云的正确姿势---油猴插件
    微信公众号开发
    F5 BIG-IP – Useful SNMP oids to monitor
    F5负载均衡 MIBs bigip oid
    常用OID(SNMP)
    有趣的深度图:可见性问题的解法
    Unity User Group 北京站:《Unity5.6新功能介绍以及HoloLens开发》
    再议Unity优化
    工作中的趣事:聊聊ref/out和方法参数的传递机制
    聊聊网络游戏同步那点事
  • 原文地址:https://www.cnblogs.com/sunsaijia/p/10063993.html
Copyright © 2011-2022 走看看