Difference between revisions of "Cogniteam/CodeConvention"

From cogniteam
Jump to: navigation, search
(Created page with "==General OOP principles== * Object-oriented programming [https://en.wikipedia.org/wiki/Object-oriented_programming OOP] * SOLID principles [https://en.wikipedia.org/wiki/SO...")
 
Line 1: Line 1:
 
==General OOP principles==
 
==General OOP principles==
 +
* Object-oriented programming [https://en.wikipedia.org/wiki/Object-oriented_programming OOP]
 +
* SOLID principles [https://en.wikipedia.org/wiki/SOLID SOLID]
 +
* Software design pattern [https://en.wikipedia.org/wiki/Software_design_pattern Desigh Patterns]
 +
 +
==Coding style and naming convention==
 +
 +
===C++ naming conventions===
 +
 +
{| class="wikitable"
 +
! Convention name !! Example
 +
|-
 +
| Upper Camel Case || UpperCamelCase
 +
|-
 +
| Lower Camel Case || lowerCamelCase
 +
|-
 +
| Upper Snake Case || UPPER_SNAKE_CASE
 +
|-
 +
| Lower Snake Case || lower_snake_case
 +
|}
 +
 +
{| class="wikitable" style="width: 100%"
 +
|-
 +
! Component !! Convention !! Example
 +
|-
 +
| Variables || Lower camel case ||  <syntaxhighlight lang="C++">
 +
int state_;
 +
MessageType messageType;
 +
 +
uint32_t countOfSomething;
 +
 +
ros::NodeHandle rosNodeHandle;
 +
</syntaxhighlight> 
 +
|-
 +
| Methods || Lower camel case || <syntaxhighlight lang="C++">
 +
void calculate();
 +
 +
int getCount();
 +
 +
int processIncomingMessages();
 +
</syntaxhighlight> 
 +
|-
 +
| Member variables || Add '_' suffix to name, '''cannot be public''' || <syntaxhighlight lang="C++">
 +
int memberVariable_;
 +
 +
std::string name_;
 +
 +
ros::ServiceClient rosServiceClient_;
 +
</syntaxhighlight> 
 +
|-
 +
| Class names || Upper camel case || <syntaxhighlight lang="C++">
 +
class Vector3;
 +
class AgentController;
 +
class MapAligner;
 +
</syntaxhighlight> 
 +
|-
 +
| [https://en.wikibooks.org/wiki/C%2B%2B_Programming/Classes/Abstract_Classes Abstract classes] || Upper camel case<br/>Prefix 'I' for interfaces - pure abstract classes without any implementations<br />Suffix 'Base' for abstract base classes with some implementations || <syntaxhighlight lang="C++">
 +
class ITextParser; // Pure abstract class - defines only interfaces without any implementations
 +
class IMapFilter;
 +
 +
class TaskBase; // Abstract class with some implementations common to all tasks
 +
class MappingBase;
 +
 +
</syntaxhighlight> 
 +
|-
 +
| Namespaces || Lower camel case || <syntaxhighlight lang="C++">
 +
namespace cognitao_utils { }
 +
 +
namespace cogniteam {
 +
namespace tools {
 +
 +
} /* namespace tools */
 +
} /* namespace cogniteam */
 +
</syntaxhighlight> 
 +
|-
 +
| Enums || Upper camel case<br />[https://stackoverflow.com/questions/18335861/why-is-enum-class-preferred-over-plain-enum Prefer enum class over regular enums] || MessageTypes, Colors<syntaxhighlight lang="C++">
 +
enum class MessageTypes {
 +
    Single = 1,
 +
    MultiPacket = 2,
 +
};
 +
 +
enum class Colors {
 +
    Red = 0x00,
 +
    Green = 0x01,
 +
    Blue = 0x02
 +
};
 +
</syntaxhighlight>
 +
|}
 +
 +
===Files and folders===
 +
 +
* Files and packages:
 +
** upper camel case for class headers and sources (MyClass.h, MyClass.cpp)
 +
** lower snake case for file containing main method (my_executable.cpp, my_ros_node.cpp, robot_driver_node.cpp)
 +
** lower snake case for package names (my_package, hamster_driver, elbit_planner)
 +
* '''DON'T USE MACROS'''
 +
* '''DON'T USE DEFINES''' (except header guards)
 +
* Why not?
 +
** http://www.stroustrup.com/bs_faq2.html#macro
 +
** [https://git.cogni.io/maytronics/maytronics/snippets/8 Try to debug this]
 +
 +
Related:
 +
* [http://wiki.ros.org/CppStyleGuide ROS C++ style guide]
 +
* [http://wiki.ros.org/ROS/Patterns/Conventions ROS naming convention]
 +
 +
 +
<syntaxhighlight lang="C++">
 +
/*
 +
* CogniteamClass.h
 +
*
 +
*  Created on: Jan 1, 2031
 +
*      Author: John Doe <johndoe@cogniteam.com>
 +
*
 +
*
 +
* Cogniteam LTD CONFIDENTIAL
 +
*
 +
* Unpublished Copyright (c) 2010-2020 Cogniteam,        All Rights Reserved.
 +
*
 +
* NOTICE:  All information contained  herein  is,  and  remains the property
 +
* of Cogniteam.  The  intellectual  and  technical  concepts  contained
 +
* herein are proprietary to Cogniteam and may  be  covered  by  Israeli  and
 +
* Foreign Patents, patents in process,  and  are  protected  by trade secret
 +
* or copyright law. Dissemination of  this  information  or  reproduction of
 +
* this material is strictly forbidden unless  prior  written  permission  is
 +
* obtained  from  Cogniteam.  Access  to  the  source  code contained herein
 +
* is hereby  forbidden  to  anyone  except  current  Cogniteam employees,
 +
* managers  or  contractors  who  have  executed  Confidentiality  and
 +
* Non-disclosure    agreements    explicitly    covering    such    access
 +
*
 +
* The copyright notice  above  does  not  evidence  any  actual  or intended
 +
* publication  or  disclosure    of    this  source  code,  which  includes
 +
* information that is confidential  and/or  proprietary,  and  is  a  trade
 +
* secret, of  Cogniteam.    ANY REPRODUCTION,  MODIFICATION,  DISTRIBUTION,
 +
* PUBLIC  PERFORMANCE,  OR  PUBLIC  DISPLAY  OF  OR  THROUGH USE  OF  THIS
 +
* SOURCE  CODE  WITHOUT  THE  EXPRESS  WRITTEN  CONSENT  OF  Cogniteam  IS
 +
* STRICTLY PROHIBITED, AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL
 +
* TREATIES.  THE RECEIPT OR POSSESSION OF  THIS SOURCE  CODE  AND/OR RELATED
 +
* INFORMATION DOES  NOT CONVEY OR IMPLY ANY RIGHTS  TO  REPRODUCE,  DISCLOSE
 +
* OR  DISTRIBUTE ITS CONTENTS, OR TO  MANUFACTURE,  USE,  OR  SELL  ANYTHING
 +
* THAT      IT    MAY    DESCRIBE,    IN    WHOLE    OR    IN    PART
 +
*
 +
*/
 +
                        // Maximum 80 characters per line        // new line 
 +
                                                                  // new line
 +
//
 +
// Always use header guards for header files
 +
//
 +
#ifndef PATH_TO_FILE_AND_FILE_NAME_
 +
#define PATH_TO_FILE_AND_FILE_NAME_
 +
                                                                  // new line
 +
                                                                  // new line
 +
//
 +
// Group includes of the same library and separate it using a new line
 +
// Order your include files from low level to higher.
 +
//  1. libstd C headers: <printf.h>, <file.h>, <math.h>
 +
//  2. libstd C++ headers: <fstream>, <thread>, <mutex>, <cmath>
 +
//  4. Other 3rd party includes: <boost/mutex.hpp>, <Qt/QtCore>, <ros/ros.h>,
 +
//                                <pcl/pcl.h>
 +
//  4. Local includes: <cogniteam/project_name3/SomeClass.h>
 +
//
 +
#include <printf.h>
 +
                                                                  // new line
 +
#include <iostream>
 +
#include <fstream>
 +
#include <mutex>
 +
                                                                  // new line
 +
#include <boost/bind.hpp>
 +
#include <boost/thread.hpp>
 +
#include <boost/thread/mutex.hpp>
 +
#include <boost/asio.hpp>
 +
#include <boost/asio/serial_port.hpp>
 +
#include <boost/system/error_code.hpp>
 +
                                                                  // new line
 +
#include <ros/ros.h>
 +
#include <std_msgs/String.h>
 +
#include <ackermann_msgs/AckermannDriveStamped.h>
 +
                                                                  // new line
 +
#include <cogniteam/AwesomeClass.h>
 +
#include <cogniteam/project_name3/JustSomeClass.h>
 +
                                                                  // new line
 +
                                                                  // new line
 +
//
 +
// Always wrap your code with a namespace
 +
//
 +
namespace cogniteam {
 +
namespace project_name {
 +
                                                                  // new line
 +
                                                                  // new line
 +
// Include other namespaces
 +
using namespace std;
 +
using namespace cogniteam::project_name2;
 +
                                                                  // new line
 +
                                                                  // new line
 +
/**
 +
* Custom color for...
 +
*/
 +
enum class CogniColor {
 +
    Red = 1,
 +
    Blue = 2,
 +
    Green
 +
};
 +
                                                                  // new line
 +
                                                                  // new line
 +
/**
 +
* High level description of class purposes
 +
* @note Comment using Doxygen's 'Javadoc style' format
 +
* @url http://www.doxygen.nl/manual/docblocks.html
 +
*/
 +
class CogniteamClass : public CogniteamBaseClass {
 +
                                                                                  // Use separate public block for constructors and descructor
 +
public:
 +
 +
    /**
 +
    * Construct a new Cogniteam Class object
 +
    */
 +
CogniteamClass();
 +
 +
    /**
 +
    * Construct a new Cogniteam Class object
 +
    * @param obj1
 +
    */
 +
CogniteamClass(const SomeClass& obj1);
 +
 +
    /**
 +
    * Copy constructor
 +
    * @note Don't forget to implement copy constructor & copy assignment operator
 +
    *      if you have pointers in your class
 +
    * @param obj1
 +
    */
 +
CogniteamClass(const CogniteamClass& obj1);
 +
 +
    /**
 +
    * Destroys the Cogniteam Class object
 +
    * @note Always declare virtual desctrutor in your classes
 +
    */
 +
virtual ~CogniteamClass();
 +
 +
public:
 +
 +
    /**
 +
    * Public type alias for convenient
 +
    */
 +
    using Ptr = shared_ptr<CogniteamClass>;
 +
 +
    using ConstPtr = shared_ptr<CogniteamClass const>;
 +
 +
public:
 +
 +
    //
 +
    // Public member methods
 +
    // NO PUBLIC VARIABLE ALLOWED - USE GETTERS AND SETTERS
 +
    //
 +
    // Getter & Setter example for member variable object_:
 +
    //
  
* Object-oriented programming [https://en.wikipedia.org/wiki/Object-oriented_programming OOP]
 
  
* SOLID principles [https://en.wikipedia.org/wiki/SOLID SOLID]
+
    /**
 +
    * Set the Var object
 +
    * @note inline setters & getters
 +
    * @note Use const methods for getters
 +
    * @note Setters and getters must be as short as possible, ideally,
 +
    *       one copy assignment and one return:  
 +
    * @param var
 +
    * @return int
 +
    */
 +
    inline void setObject(Object& object) {
 +
        object_ = object;
 +
    }
 +
   
 +
    /**
 +
    * Gets the Object object
 +
    * @return Object
 +
    */
 +
    inline Object getObject() const {
 +
        return object_;
 +
    }
 +
 
 +
    /**
 +
    * Use prefix T for template parameters (MessageT, ServiceT, PacketT...)
 +
    * @tparam ObjectT
 +
    * @param object
 +
    */
 +
    template <typename ObjectT>
 +
    void templateMethod(const ObjectT& object) {
 +
        // ...
 +
    }
 +
 
 +
protected:
 +
 
 +
    //
 +
    // Protected member methods
 +
    //
 +
 
 +
    /**
 +
    * Protected method, visible by this and derived classes
 +
    * @return int
 +
    */
 +
    int protectedMethod();
 +
 
 +
protected:
 +
 
 +
    //
 +
    // Protected member variables
 +
    //
 +
 
 +
    /**
 +
    * Protected member variable, visible by this and derived classes
 +
    */
 +
    int protectedMemberVariable_ = 0;
 +
 
 +
private:
 +
 
 +
    //
 +
    // Private member methods
 +
    //
  
* Software design pattern [https://en.wikipedia.org/wiki/Software_design_pattern Desigh Patterns]
+
    /**
 +
    * Runs my algorithm
 +
    * @param param1 First parameter
 +
    * @param param2 Second parameter
 +
    * @param param3 Another parameter
 +
    * @return true If success
 +
    * @return false If failure
 +
    */
 +
    bool runAlgorithm(double param1, double param2, double param3);
  
 +
    /**
 +
    * Calculates a number such that...
 +
    * @param param1 First param for calculationg
 +
    * @return double Calculation result
 +
    */
 +
    double calculateNumber(double param1) const;
  
==Coding style and naming convention==
+
private:
  
'''C++'''
+
    //
 +
    // Private member methods
 +
    //
  
All changes must conform to [http://wiki.ros.org/CppStyleGuide ROS C++ style guide]
+
    /**
 +
    * Const member example, upper case with underscore, place const's first
 +
    */
 +
const string CONST_MEMBER_STRING = "monitor_red";
  
'''ROS'''
+
    /**
 +
    * Private variable, visible by this class only
 +
    */
 +
Object object_;
  
Packge names, topic, message files and all ROS related assets must conform to [http://wiki.ros.org/ROS/Patterns/Conventions ROS naming convention]
+
};
 +
                                                                  // new line
 +
                                                                  // new line
 +
} /* namespace widgets */
 +
} /* namespace ocu */
 +
} /* namespace lynx */
 +
                                                                  // new line
 +
                                                                  // new line
 +
#endif /* PATH_TO_FILE_AND_FILE_NAME_ */
 +
                                                                  // new line
 +
</syntaxhighlight>

Revision as of 13:45, 30 December 2019

General OOP principles

Coding style and naming convention

C++ naming conventions

Convention name Example
Upper Camel Case UpperCamelCase
Lower Camel Case lowerCamelCase
Upper Snake Case UPPER_SNAKE_CASE
Lower Snake Case lower_snake_case
Component Convention Example
Variables Lower camel case <syntaxhighlight lang="C++">

int state_; MessageType messageType;

uint32_t countOfSomething;

ros::NodeHandle rosNodeHandle; </syntaxhighlight>

Methods Lower camel case <syntaxhighlight lang="C++">

void calculate();

int getCount();

int processIncomingMessages(); </syntaxhighlight>

Member variables Add '_' suffix to name, cannot be public <syntaxhighlight lang="C++">

int memberVariable_;

std::string name_;

ros::ServiceClient rosServiceClient_; </syntaxhighlight>

Class names Upper camel case <syntaxhighlight lang="C++">

class Vector3; class AgentController; class MapAligner; </syntaxhighlight>

Abstract classes Upper camel case
Prefix 'I' for interfaces - pure abstract classes without any implementations
Suffix 'Base' for abstract base classes with some implementations
<syntaxhighlight lang="C++">

class ITextParser; // Pure abstract class - defines only interfaces without any implementations class IMapFilter;

class TaskBase; // Abstract class with some implementations common to all tasks class MappingBase;

</syntaxhighlight>

Namespaces Lower camel case <syntaxhighlight lang="C++">

namespace cognitao_utils { }

namespace cogniteam { namespace tools {

} /* namespace tools */ } /* namespace cogniteam */ </syntaxhighlight>

Enums Upper camel case
Prefer enum class over regular enums
MessageTypes, Colors<syntaxhighlight lang="C++">

enum class MessageTypes {

   Single = 1,
   MultiPacket = 2,

};

enum class Colors {

   Red = 0x00,
   Green = 0x01,
   Blue = 0x02

}; </syntaxhighlight>

Files and folders

  • Files and packages:
    • upper camel case for class headers and sources (MyClass.h, MyClass.cpp)
    • lower snake case for file containing main method (my_executable.cpp, my_ros_node.cpp, robot_driver_node.cpp)
    • lower snake case for package names (my_package, hamster_driver, elbit_planner)
  • DON'T USE MACROS
  • DON'T USE DEFINES (except header guards)
  • Why not?

Related:


<syntaxhighlight lang="C++"> /*

* CogniteamClass.h
* 
*  Created on: Jan 1, 2031
*      Author: John Doe <johndoe@cogniteam.com>
*
*
* Cogniteam LTD CONFIDENTIAL
*
* Unpublished Copyright (c) 2010-2020 Cogniteam,        All Rights Reserved.
*
* NOTICE:  All information contained  herein  is,  and  remains the property
* of Cogniteam.   The   intellectual   and   technical   concepts  contained
* herein are proprietary to Cogniteam and may  be  covered  by  Israeli  and
* Foreign Patents, patents in process,  and  are  protected  by trade secret
* or copyright law. Dissemination of  this  information  or  reproduction of
* this material is strictly forbidden unless  prior  written  permission  is
* obtained  from  Cogniteam.  Access  to  the  source  code contained herein
* is hereby   forbidden   to   anyone  except  current  Cogniteam employees,
* managers   or   contractors   who   have   executed   Confidentiality  and
* Non-disclosure    agreements    explicitly    covering     such     access
*
* The copyright notice  above  does  not  evidence  any  actual  or intended
* publication  or  disclosure    of    this  source  code,   which  includes
* information that is confidential  and/or  proprietary,  and  is  a   trade
* secret, of   Cogniteam.    ANY REPRODUCTION,  MODIFICATION,  DISTRIBUTION,
* PUBLIC   PERFORMANCE,  OR  PUBLIC  DISPLAY  OF  OR  THROUGH USE   OF  THIS
* SOURCE  CODE   WITHOUT   THE  EXPRESS  WRITTEN  CONSENT  OF  Cogniteam  IS
* STRICTLY PROHIBITED, AND IN VIOLATION OF APPLICABLE LAWS AND INTERNATIONAL
* TREATIES.  THE RECEIPT OR POSSESSION OF  THIS SOURCE  CODE  AND/OR RELATED
* INFORMATION DOES  NOT CONVEY OR IMPLY ANY RIGHTS  TO  REPRODUCE,  DISCLOSE
* OR  DISTRIBUTE ITS CONTENTS, OR TO  MANUFACTURE,  USE,  OR  SELL  ANYTHING
* THAT      IT     MAY     DESCRIBE,     IN     WHOLE     OR     IN     PART
*
*/
                        // Maximum 80 characters per line        // new line  
                                                                 // new line

// // Always use header guards for header files //

  1. ifndef PATH_TO_FILE_AND_FILE_NAME_
  2. define PATH_TO_FILE_AND_FILE_NAME_
                                                                 // new line
                                                                 // new line

// // Group includes of the same library and separate it using a new line // Order your include files from low level to higher. // 1. libstd C headers: <printf.h>, <file.h>, <math.h> // 2. libstd C++ headers: <fstream>, <thread>, <mutex>, <cmath> // 4. Other 3rd party includes: <boost/mutex.hpp>, <Qt/QtCore>, <ros/ros.h>, // <pcl/pcl.h> // 4. Local includes: <cogniteam/project_name3/SomeClass.h> //

  1. include <printf.h>
                                                                 // new line
  1. include <iostream>
  2. include <fstream>
  3. include <mutex>
                                                                 // new line
  1. include <boost/bind.hpp>
  2. include <boost/thread.hpp>
  3. include <boost/thread/mutex.hpp>
  4. include <boost/asio.hpp>
  5. include <boost/asio/serial_port.hpp>
  6. include <boost/system/error_code.hpp>
                                                                 // new line
  1. include <ros/ros.h>
  2. include <std_msgs/String.h>
  3. include <ackermann_msgs/AckermannDriveStamped.h>
                                                                 // new line
  1. include <cogniteam/AwesomeClass.h>
  2. include <cogniteam/project_name3/JustSomeClass.h>
                                                                 // new line
                                                                 // new line

// // Always wrap your code with a namespace // namespace cogniteam { namespace project_name {

                                                                 // new line
                                                                 // new line

// Include other namespaces using namespace std; using namespace cogniteam::project_name2;

                                                                 // new line
                                                                 // new line

/**

* Custom color for...
*/

enum class CogniColor {

   Red = 1, 
   Blue = 2,
   Green

};

                                                                 // new line
                                                                 // new line

/**

* High level description of class purposes 
* @note Comment using Doxygen's 'Javadoc style' format
* @url http://www.doxygen.nl/manual/docblocks.html
*/

class CogniteamClass : public CogniteamBaseClass {

                                                                                  // Use separate public block for constructors and descructor

public:

   /**
    * Construct a new Cogniteam Class object
    */

CogniteamClass();

   /**
    * Construct a new Cogniteam Class object
    * @param obj1 
    */

CogniteamClass(const SomeClass& obj1);

   /**
    * Copy constructor
    * @note Don't forget to implement copy constructor & copy assignment operator
    *       if you have pointers in your class
    * @param obj1 
    */

CogniteamClass(const CogniteamClass& obj1);

   /**
    * Destroys the Cogniteam Class object
    * @note Always declare virtual desctrutor in your classes
    */

virtual ~CogniteamClass();

public:

   /**
    * Public type alias for convenient
    */
   using Ptr = shared_ptr<CogniteamClass>;
   using ConstPtr = shared_ptr<CogniteamClass const>;

public:

   //
   // Public member methods
   // NO PUBLIC VARIABLE ALLOWED - USE GETTERS AND SETTERS
   //
   // Getter & Setter example for member variable object_:
   //


   /**
    * Set the Var object
    * @note inline setters & getters
    * @note Use const methods for getters
    * @note Setters and getters must be as short as possible, ideally, 
    *       one copy assignment and one return: 
    * @param var 
    * @return int 
    */
   inline void setObject(Object& object) {
       object_ = object;
   }
   
   /**
    * Gets the Object object
    * @return Object 
    */
   inline Object getObject() const {
       return object_;
   }
   /**
    * Use prefix T for template parameters (MessageT, ServiceT, PacketT...)
    * @tparam ObjectT 
    * @param object 
    */
   template <typename ObjectT>
   void templateMethod(const ObjectT& object) {
       // ...
   }

protected:

   //
   // Protected member methods
   //
   /**
    * Protected method, visible by this and derived classes
    * @return int 
    */
   int protectedMethod();

protected:

   //
   // Protected member variables
   //
   /**
    * Protected member variable, visible by this and derived classes
    */
   int protectedMemberVariable_ = 0;

private:

   //
   // Private member methods
   //
   /**
    * Runs my algorithm 
    * @param param1 First parameter
    * @param param2 Second parameter
    * @param param3 Another parameter
    * @return true If success
    * @return false If failure
    */
   bool runAlgorithm(double param1, double param2, double param3);
   /**
    * Calculates a number such that...
    * @param param1 First param for calculationg
    * @return double Calculation result
    */
   double calculateNumber(double param1) const;

private:

   //
   // Private member methods
   //
   /**
    * Const member example, upper case with underscore, place const's first
    */

const string CONST_MEMBER_STRING = "monitor_red";

   /**
    * Private variable, visible by this class only
    */

Object object_;

};

                                                                 // new line
                                                                 // new line

} /* namespace widgets */ } /* namespace ocu */ } /* namespace lynx */

                                                                 // new line
                                                                 // new line
  1. endif /* PATH_TO_FILE_AND_FILE_NAME_ */
                                                                 // new line

</syntaxhighlight>