KEMBAR78
Coding Guidelines - Crafting Clean Code | PDF
CRAFTING CLEAN CODE
Ganesh Samarthyam
“Keeping “clean” is a habit - it’s not to
do with “skills” or “ability”!
WARM-UP EXERCISE
ASSUME MANY PLACES YOU HAVE SUCH CODE- HOW TO IMPROVE?
#include <vector>
#include <iostream>
using namespace std;
bool validate_temperature_measures(vector<int> &measures) {
for(vector<int>::iterator i = measures.begin(); i != measures.end(); ++i ) {
if( *i < 0 || *i > 100) {
return false;
}
}
return true;
}
int main() {
vector<int> measures = { 23, 66, 25, 85, 110, 45, 34, 90 };
cout << "valid measures? "
<< std::boolalpha << validate_temperature_measures(measures) << endl;
}
ATTEMPT #1
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
template<typename T>
class is_outside_range : public unary_function<T, bool> {
public:
is_outside_range(const T& low, const T& high) : low_(low), high_(high) {}
bool operator()( const T& val ) const {return val < low_ || val > high_; }
private:
T low_, high_;
};
bool validate_temperature_measures(vector<int> &measures) {
vector<int>::iterator result = find_if(measures.begin(), measures.end(),
is_outside_range<int>(0, 100));
return result == measures.end();
}
int main() {
vector<int> measures = { 23, 66, 25, 85, 10, 45, 34, 90 };
cout << "valid measures? " << std::boolalpha <<
validate_temperature_measures(measures) << endl;
}
ATTEMPT #2
#include <vector>
#include <algorithm>
#include <functional>
#include <iostream>
using namespace std;
bool validate_temperature_measures(vector<int> &measures) {
function<bool(int)> temperature_validator =
[](const int value) {
const int low = 0;
const int high = 100;
return (value < low) || (value > high);
};
vector<int>::iterator result = find_if(measures.begin(), measures.end(),
temperature_validator);
return result == measures.end();
}
int main() {
vector<int> measures = { 23, 66, 25, 85, 10, 45, 34, 90 };
cout << "valid measures? " << std::boolalpha <<
validate_temperature_measures(measures) << endl;
}
GETTING STARTED
ESSENTIALS
➤ Ensure traceability within code
➤ Do not write “sloppy code”
➤ Provide necessary copyright notice, change logs, etc. in each
source and header files
FORMATTING
➤ “Consistency” is key to formatting
➤ Example: placement of curly braces - “{“ and “}”
➤ Another obvious example: tabs vs. whitespaces
➤ Keep lines within 80 characters
➤ Ensure “density” is not too high
➤ E.g., leave out enough a linespace between group of
statements
➤ Have an ordering of member functions, data members, etc.
➤ Ensure proper intendation
MEANINGFUL NAMES
➤ Use intention-revealing names
int d; // elapsed time in days
int elapsedTimeInDays;
➤ Use searchable names
for(int j = 0; j < 34; j++)
s+= (t(j)*4)/5;
int realDaysPerIdealDay = 4;
const int WORK_DAYS_PER_WEEK = 5;
int sum = 0;
for(int task; task < NUMBER_OF_TASKS; j++) {
int realTaskDays = taskEstimate[task] * realDaysPerIdealDay;
int realTaskWeeks = (realDays / WORK_DAYS_PER_WEEK);
sum += realTaskWeeks;
}
Clean Code: A Handbook of Agile Software Craftsmanship, Robert C. Martin, Prentice Hall, 2008
NAMING
➤ Avoid Hungarian notation and member prefixes
➤ Class names should have noun or noun phrases (and not be a
verb)
➤ Method names should have verb or verb phrase names
➤ Avoid typos and smelling mistakes in the code
COMMENTS
➤ Provide good “internal documentation”
➤ Comments do not make up for bad code
➤ Explain yourself in code
➤ Explain intent
➤ Avoid commenting-out code
➤ Avoid redundant comments
➤ Provide mandated comments
➤ Use position markers sparingly (e.g., // Actions ////////)
Clean Code: A Handbook of Agile Software Craftsmanship, Robert C. Martin, Prentice Hall, 2008
FUNCTIONS / METHODS
➤ Avoid macros - use inline functions instead
➤ Method names - neither too long, nor too short
➤ Keep parameter list small (not more than 4 or so parameters)
➤ Avoid “out” parameters - prefer return values instead
➤ Avoid friend functions
➤ Prefer const methods
➤ Ensure proper return from all paths
➤ Strive for exception safety
FUNCTIONS / METHODS
➤ Keep nesting level of functions low (not more than 3 or 4
levels deep)
➤ Keep Cyclomatic complexity low (less than 10 per method)
➤ Keep lines size small (more than 10 or so becomes difficult to
grasp)
➤ Avoid functions doing many things - do one thing (e.g.,
realloc does too many things)
➤ Avoid “stateful-functions” (e.g., strtok)
CLASSES
➤ Prefer one class per file
➤ Limit the number of members in a class
➤ Avoid public data members
➤ Limit the accessibility of the class members
➤ Have a ordering for the methods and data members; order
public, private, and protected members
➤ Keep the complexity of classes low - i.e., Weighted Methods
per Class (WMC) keep it low like 25 or 30
➤ Avoid “struct-like” classes
HARDCODING
➤ Avoid “hard-coded logic”
➤ Avoid “magic numbers”
➤ Avoid “magic strings”
“Adopt a coding standard and adhere
to it (as a team!)
“Code without unit tests is legacy
code!
CODING GUIDELINES
MISRA C/C++
https://www.misra-cpp.com/MISRACHome/tabid/128/Default.aspx
CERT C++
https://www.cert.org/downloads/secure-coding/assets/sei-cert-cpp-coding-standard-2016-v01.pdf
JSF++
http://www.stroustrup.com/JSF-AV-rules.pdf
Designed by Lockheed Martin for Joint Strike Fighter - Air Vehicle coding standard for C++
HIGH-INTEGRITY C++ CODING STANDARD
http://www.codingstandard.com/section/index/
GOOGLE C++ STYLE GUIDE
https://google.github.io/styleguide/cppguide.html
C++ CORE GUIDELINES
http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines
ganesh@codeops.tech @GSamarthyam
www.codeops.tech slideshare.net/sgganesh
+91 98801 64463 bit.ly/sgganesh

Coding Guidelines - Crafting Clean Code

  • 1.
  • 3.
    “Keeping “clean” isa habit - it’s not to do with “skills” or “ability”!
  • 4.
  • 5.
    ASSUME MANY PLACESYOU HAVE SUCH CODE- HOW TO IMPROVE? #include <vector> #include <iostream> using namespace std; bool validate_temperature_measures(vector<int> &measures) { for(vector<int>::iterator i = measures.begin(); i != measures.end(); ++i ) { if( *i < 0 || *i > 100) { return false; } } return true; } int main() { vector<int> measures = { 23, 66, 25, 85, 110, 45, 34, 90 }; cout << "valid measures? " << std::boolalpha << validate_temperature_measures(measures) << endl; }
  • 6.
    ATTEMPT #1 #include <vector> #include<algorithm> #include <iostream> using namespace std; template<typename T> class is_outside_range : public unary_function<T, bool> { public: is_outside_range(const T& low, const T& high) : low_(low), high_(high) {} bool operator()( const T& val ) const {return val < low_ || val > high_; } private: T low_, high_; }; bool validate_temperature_measures(vector<int> &measures) { vector<int>::iterator result = find_if(measures.begin(), measures.end(), is_outside_range<int>(0, 100)); return result == measures.end(); } int main() { vector<int> measures = { 23, 66, 25, 85, 10, 45, 34, 90 }; cout << "valid measures? " << std::boolalpha << validate_temperature_measures(measures) << endl; }
  • 7.
    ATTEMPT #2 #include <vector> #include<algorithm> #include <functional> #include <iostream> using namespace std; bool validate_temperature_measures(vector<int> &measures) { function<bool(int)> temperature_validator = [](const int value) { const int low = 0; const int high = 100; return (value < low) || (value > high); }; vector<int>::iterator result = find_if(measures.begin(), measures.end(), temperature_validator); return result == measures.end(); } int main() { vector<int> measures = { 23, 66, 25, 85, 10, 45, 34, 90 }; cout << "valid measures? " << std::boolalpha << validate_temperature_measures(measures) << endl; }
  • 8.
  • 9.
    ESSENTIALS ➤ Ensure traceabilitywithin code ➤ Do not write “sloppy code” ➤ Provide necessary copyright notice, change logs, etc. in each source and header files
  • 10.
    FORMATTING ➤ “Consistency” iskey to formatting ➤ Example: placement of curly braces - “{“ and “}” ➤ Another obvious example: tabs vs. whitespaces ➤ Keep lines within 80 characters ➤ Ensure “density” is not too high ➤ E.g., leave out enough a linespace between group of statements ➤ Have an ordering of member functions, data members, etc. ➤ Ensure proper intendation
  • 11.
    MEANINGFUL NAMES ➤ Useintention-revealing names int d; // elapsed time in days int elapsedTimeInDays; ➤ Use searchable names for(int j = 0; j < 34; j++) s+= (t(j)*4)/5; int realDaysPerIdealDay = 4; const int WORK_DAYS_PER_WEEK = 5; int sum = 0; for(int task; task < NUMBER_OF_TASKS; j++) { int realTaskDays = taskEstimate[task] * realDaysPerIdealDay; int realTaskWeeks = (realDays / WORK_DAYS_PER_WEEK); sum += realTaskWeeks; } Clean Code: A Handbook of Agile Software Craftsmanship, Robert C. Martin, Prentice Hall, 2008
  • 12.
    NAMING ➤ Avoid Hungariannotation and member prefixes ➤ Class names should have noun or noun phrases (and not be a verb) ➤ Method names should have verb or verb phrase names ➤ Avoid typos and smelling mistakes in the code
  • 13.
    COMMENTS ➤ Provide good“internal documentation” ➤ Comments do not make up for bad code ➤ Explain yourself in code ➤ Explain intent ➤ Avoid commenting-out code ➤ Avoid redundant comments ➤ Provide mandated comments ➤ Use position markers sparingly (e.g., // Actions ////////) Clean Code: A Handbook of Agile Software Craftsmanship, Robert C. Martin, Prentice Hall, 2008
  • 14.
    FUNCTIONS / METHODS ➤Avoid macros - use inline functions instead ➤ Method names - neither too long, nor too short ➤ Keep parameter list small (not more than 4 or so parameters) ➤ Avoid “out” parameters - prefer return values instead ➤ Avoid friend functions ➤ Prefer const methods ➤ Ensure proper return from all paths ➤ Strive for exception safety
  • 15.
    FUNCTIONS / METHODS ➤Keep nesting level of functions low (not more than 3 or 4 levels deep) ➤ Keep Cyclomatic complexity low (less than 10 per method) ➤ Keep lines size small (more than 10 or so becomes difficult to grasp) ➤ Avoid functions doing many things - do one thing (e.g., realloc does too many things) ➤ Avoid “stateful-functions” (e.g., strtok)
  • 16.
    CLASSES ➤ Prefer oneclass per file ➤ Limit the number of members in a class ➤ Avoid public data members ➤ Limit the accessibility of the class members ➤ Have a ordering for the methods and data members; order public, private, and protected members ➤ Keep the complexity of classes low - i.e., Weighted Methods per Class (WMC) keep it low like 25 or 30 ➤ Avoid “struct-like” classes
  • 17.
    HARDCODING ➤ Avoid “hard-codedlogic” ➤ Avoid “magic numbers” ➤ Avoid “magic strings”
  • 18.
    “Adopt a codingstandard and adhere to it (as a team!)
  • 19.
    “Code without unittests is legacy code!
  • 20.
  • 21.
  • 22.
  • 23.
    JSF++ http://www.stroustrup.com/JSF-AV-rules.pdf Designed by LockheedMartin for Joint Strike Fighter - Air Vehicle coding standard for C++
  • 24.
    HIGH-INTEGRITY C++ CODINGSTANDARD http://www.codingstandard.com/section/index/
  • 25.
    GOOGLE C++ STYLEGUIDE https://google.github.io/styleguide/cppguide.html
  • 26.
  • 27.