How to do simple code refactoring? (with example

Concept

  • programming indicators
    • robustness
    • Reusability
    • maintainability
    • performance

When we add new content to the code, we need to review the code we wrote before to find out the commonality, that is, the part that can be reused, so that the code becomes more concise and can be Better respond to possible future feature additions and deletions.

The following will talk about how to refactor code through a simple topic.

Title

Source: https://www.luogu.com.cn/problem/P5740


The idea of this question is not difficult. If it is done with a structure, it is obvious that for any student, ta includes members such as name, three grades, and total score. Then my initial idea was to create a Student structure to store these data, and then open an array students to store each Student, so that at the end Comparison.

struct Student{<!-- -->
    std::string name;
    int chi;
    int math;
    int eng;
    int total;
};

std::vector<Student> students;

Next, the input is processed. It is a normal idea to input the data required by the topic in turn for each row.

int n;
std::cin >> n;

 for(int i{<!-- -->0};i<n;i + + ){<!-- -->
        Student* tmp = new Student;
        std::cin >> tmp->name >> tmp->chi
        >> tmp->math >> tmp->eng;
        \t\t 
        tmp->total = tmp->chi + tmp->math + tmp->eng;
        students.push_back(*tmp);
        delete tmp;
    }

The last thing is to find the most powerful student. At first, I thought about sorting students directly (according to total in descending order), and finally output the first element directly That’s fine. To do this, we need to create a function as our sorting criterion.

bool cmp(Student s1, Student s2){<!-- -->
    return s1.total > s2.total;
}

Then this question can be done.

std::sort(students.begin(),students.end(),cmp);
Student best = students. front();
std::cout << best.name << " " << best.chi << " "
          << best.math << " " " << best.eng << "\
";

Code refactoring

Reviewing the code we wrote, there are several obvious problems:

  1. If the number of Student to be output is large (although it is not required by this question), should we take the trouble to type the variable names of name chinese math eng total every time ?
  2. Is it really necessary to open an array? It is a bit troublesome to push an element every time, and finally perform our own definition of sorting.

Based on the above thinking, we started code refactoring. Note that an important criterion for code refactoring is to extract reusable parts.

Part 1

The effect we strive to achieve is that we can directly use std::cin >> studentObj and std::cout << studentObj, so it is naturally associated with operator overloading strong>.

//Because I used the new operator below, so the pointer is passed in here
std::istream & amp; operator>>(std::istream & amp; is, Student* s){<!-- -->
    is >> s->name >> s->chi >> s->math >> s->eng;
    s->total = s->chi + s->math + s->eng;
    return is;
}

// Using a reference as a return value enables continuous input and output
std::ostream & amp; operator<<(std::ostream & amp; os, Student s){<!-- -->
    os << s.name << " " << s.chi << " " << s.math << " " << s.eng;
    return os;
}

In this way, our original code can be simplified as

for(int i{<!-- -->0};i<n;i ++ ){<!-- -->
        Student* tmp = new Student;
        std::cin >> tmp;
         // ---snip---
    }

Second part

We don’t need to open the array at all, just use an initial value Student best, and compare the two for each new input student. Swap if the newly entered student has a higher total score.

 Student best;
  best.total = -1; // deal with the situation where the scores are all 0

Just compare at the end.

for(int i{<!-- -->0};i<n;i ++ ){<!-- -->
        Student* tmp = new Student;
        std::cin >> tmp;
        if(tmp->total > best.total)
            best = *tmp;
        delete tmp;
    }

    std::cout << best;

Summary

In some cases, time is limited, and there is nothing wrong with writing fast, messy, and messy code. But when practicing, even if it is already Accepted, you can review your code more and find out where you can optimize it.
In the end, I am just a college student who has not been introduced for a long time, and there are bound to be deficiencies in both the concept and the way I optimize the code above. Welcome to exchange and correct me!

Full code attached
Before refactoring:

#include
#include 
#include
#include 

struct Student{
    std::string name;
    int chi;
    int math;
    int eng;
    int total;
};

bool cmp(Student s1, Student s2){<!-- -->
    return s1.total > s2.total;
}

int main(){
    int n;
    std::cin >> n;

    std::vector students;
    
    for(int i{0};i
        Student* tmp = new Student;
        std::getline(std::cin,tmp->name,' ');
        std::cin >> tmp->chi >> tmp->math >> tmp->eng;
        tmp->total = tmp->chi + tmp->math + tmp->eng;
        students.push_back(*tmp);
        delete tmp;
    }

    std::sort(students.begin(),students.end(),cmp);
    Student best = students. front();
    std::cout << best.name << " " << best.chi << " "
              << best.math << " " " << best.eng << "\
";

    return 0;
}

After refactoring:

#include<iostream>
#include<string>
#include <algorithm>

struct Student{<!-- -->
    std::string name;
    int chi;
    int math;
    int eng;
    int total;
};

std::istream & amp; operator>>(std::istream & amp; is, Student* s){<!-- -->
    is >> s->name >> s->chi >> s->math >> s->eng;
    s->total = s->chi + s->math + s->eng;
    return is;
}

std::ostream & amp; operator<<(std::ostream & amp; os, Student s){<!-- -->
    os << s.name << " " << s.chi << " " << s.math << " " << s.eng;
    return os;
}

int main(){<!-- -->
    int n;
    std::cin >> n;

    Student best;
    best.total = -1;
    
    for(int i{<!-- -->0};i<n;i + + ){<!-- -->
        Student* tmp = new Student;
        std::cin >> tmp;
        if(tmp->total > best.total)
            best = *tmp;
        delete tmp;
    }

    std::cout << best;
    return 0;
}
syntaxbug.com © 2021 All Rights Reserved.