Oovcde Index
Viewing a Class for Composition
Sometimes a class grows too large, and needs to be refactored. In
some cases, it can be difficult to determine what will result in a
clean separation of multiple classes.
The Oovcde program can display all of the data members and functions of
a class and show how they are related. The C++ code is parsed and
the diagrams are created automatically.
The following shows a class portion diagram in the Oovcde program, and
shows an example "Package" class. The data members are
shown in rectangles, and the member functions are shown in ellipses.
The arrows show the direction of the dependency.
Some notes about this example:
- The RootDirPackage class is a base class that is accessed by
setCompileInfo, one of the constructors and the setLinkInfo methods.
- One of the constructors and the destructor are empty, and
could be deleted.
- The set link and get link functions reference the link argument
data member,
but don't reference the compile argument data member.
- The load map and save map functions reference both the
compile and link argument daa members.
Run the following to view these diagrams.
- Download the Oovcde Windows or Linux binaries from Sourceforge or
download the source from
SourceForge
or GitHub
- Extract the downloaded file to any location
- Run the oovcde program from the bin directory
- Run File/New Project from the menu and browse to a C++ project
of your choice. To view the Oovcde source, run File/Open Project
from the menu and browse to the trunk/test directory and select
the trunk-oovcde-... file for linux or windows and press the
Open button
- Wait for the analysis to complete.
- Click on the Portion tab and select a class to display a
portion diagram
CppParser Example
Now we move on to an example of a class that needs to be refactored.
This class is used in the Oovcde .cpp parser. The Oovcde program
shows that it is in the module with the highest number of lines in
all of the Oovcde source code, although the complexity is not the highest.
This class is not the cleanest
class to analyze since it uses function pointers to global functions called
by the clang visitor functions, but since this class was the inspiration
for the portion diagrams, it seems like a worthy example.
For this refactoring, it is useful to think about how functions can
be rearranged based on the data members.
- For example, the mModelData member is only used by functions
in the top half of the graph for creation of classes and data
types.
- Another example is that there looks like a bit of statement code
related to the mStatements and mSwitchContexts members.
An important aspect is to think about the lifetimes of the
data members. The mOperation and mClassifier members are only used while
parsing classes and operations.
CppParser Example - Post Refactor
For the first refactoring, the model data was moved into a new class called
ParserModelData.
The portion diagram shows a bit more than a class diagram since a typical
class diagram would only show the following.
The remaining CppParser class is shown below.
The improvements that resulted are:
- The interface to the model data used to be pretty large. Now the
interface is only what the ParserModelData exposes. A few new
methods were added (setLineStats, addAssociation, addParsedModule),
which makes it easy to see what the interface to the model data is.
- 150 lines of code were removed from the CppParser class into a separate file.
At this point, there are some tradeoffs for refactoring further. The most
likely candidates are to move the following data members into a
CppOperationParser class:
- mOperation
- mSwitchContexts
- mStatementRecurseLevel
- mStatements
On the one hand, the CppParser class size would be reduced, and
the operation parts would be separated, but on the other hand, leaving
the CppParser class as is means it contains all parsing functionality.
Other Notes
Some other notes about portion diagrams:
- An attribute only used once could mean it could be eliminated. A counter
example would be some data that is retained between calls.
- A method that doesn't use an attribute could be made static if
it does not call other non-static methods and is not virtual.
Other notes about the Oovcde program:
- The Oovcde "Member Usage" feature can be used to find classes with
unused attributes.
- The Oovcde complexity or line count features can be used to find which classes
could be refactored.