The more complex the code, the more important this communication is. Complex code bases rely on abstractions to make them more manageable. But abstractions only help when programmers understand those abstractions.
Unified Modeling Language (UML) is a graphical language for visualizing, specifying, constructing, and documenting the artifacts of a software system. There are many different kinds of diagrams used in UML and we wonβt attempt to cover them all.
UML class diagrams are one of the most common types of UML diagrams. A class diagram defines a graphical way to summarize the state (member variables) and behaviors (member functions or methods) of an object.
Each class is represented by a box with three sections. The top section has the name of the class. The next section a list of member variables. And the last section has a list of the methods.
The diagram format is fairly simple, but there are a few quirks to get used to. The sections are used to store variables and methods, not private versus public members. In UML, the plus sign (+) identifies a public member while a minus sign (-) indicates a private one. Usually, all of the variables (second section) will be private and all of the functions (third sections) will be public. But if there is a private function, it still belongs in the third section.
In addition, UML is designed to be language independent. So it does not use the syntax of any particular programming language. Instead, it uses a language-independent syntax. To identify the types of members, parameters, and return types UML places them after the variable or function name. For example, in UML we write x: int rather than C++ syntax, int x. When a function has the return type void, we simply do not specify a type for that function.
Class diagrams show a class. They represent information about data types available to the compiler. There is only one Point class no matter how many Point objects get created.
Other types of diagrams, like memory diagrams focus on particular objects that exist at run time. A memory diagram might show multiple Point objects as at runtime we can create many instances of the class.
When writing documentation for a class, we typically want to document all of the functions. They typically include the entire public portion of the interface to the class. And that is the part that other programmers should be interacting with. In addition, it is a good idea to comment the class itself with a description of what it is intended to represent.
We do not necessarily need to document the member variables as they are the hidden information other programmers shouldnβt be worried about. But to help anyone who does need to maintain the class, it can be useful to add comments with any key information about them. For instance, if our point class assumed that the units were centimeters, and that was important for anyone working on the code to understand that, we would likely want to document that next to m_x and m_y.
/**
* @brief Represents a point in 2D space.
*
* A longer description can go here, explaining the purpose of the class.
*/
class Point {
public:
/**
* @brief Construct a new Point object
*
* @param x starting x coordinate
* @param y starting y coordinate
*/
Point(double x, double y) {
m_x = x;
m_y = y;
}
/**
* @brief Get the y coordinate of the point
*
* @return double y coordinate
*/
double getX() {
return m_x;
}
/**
* @brief Change the location of the point by dx and dy
*
* @param dx change in x coordinate
* @param dy change in y coordinate
*/
void shift(double dx, double dy) {
m_x += dx;
m_y += dy;
}
private:
/// @brief x coordinate of the point. Measured in cm
double m_x
/// @brief y coordinate of the point. Measured in cm
double m_y;
};
Note16.9.2.
As noted when we introduced Doxygen style commenting for functions, we often omit the full comments for classes in this text. This is done to minimize the amount of code you need to read through to find what is new or interesting in each example.