The example C++ code from the GoF (Gang of Four) book Design Patterns has had its dependencies analysed with DeepEnds. Certain examples have been refactored to remove circular dependencies enabled by forward declaration of classes. These cycles in the graph serve to reduce the ability to subsequently modify the code with ease.
DeepEnds is distributed as both a Visual Studio extension and as a NuGet package. It creates a set of nested graphs from source code and calculates various statistics on the individual graphs. These graphs and statistics are then saved in various formats, in this case the C++ source code from the Visual Studio solution was parsed with libclang and a report produced via Doxygen.
DeepEnds takes an agnostic view as to how the dependencies originate. The libclang based parser does not differentiate between constructing classes by inheritance as opposed to composition, it also picks up usage within the contents of methods. So it is also agnostic as to whether the code is object orientated, in fact the original C++ parser just parses the source files for include statements and nests the resulting nodes according to the corresponding Visual Studio filter. The include statement based parser is thus similar to the physical cycle based analysis of Bloomberg's waf verify tool. In fact if the levelization technique of John Lakos has been applied to the code then the libclang based parser will execute more swiftly.
The source of the C++ example code has been extracted from the Gang of Four book and inserted into a Visual Studio project for each Design Pattern. The code has been altered to ensure that it compiles and then all template definitions have been transformed into normal classes to overcome a limitation of the parser. The output report has had various of its images of the graphs taken for this article and, where it warns of a cycle in the graph, the corresponding example has been analysed and refactored. Cycles are observed in the graphs for
- Creational Patterns : Singleton
- Structural Patterns : Composite, Facade
- Behavioural Patterns : Interpreter, Mediator, Observer, State, Visitor
The GoF example (source code) contains no cycles but is rather busy. To digress, a typical refactoring would create a Bombed namespace and place BombedMazeFactory, BombedWall and RoomWithABomb into it. The resulting graph would then have those 3 classes replaced by one node representing the namespace.
The GoF example (source code)
The GoF example (source code)
The GoF example (source code)
The GoF examples (first source code, second, third)
the cycle in the last graph may be removed by inserting an interface as shown in variant1 (source code)
The GoF example (source code)
The GoF example (source code)
The GoF examples (first source code, second)
the cycle in the first graph may be removed, in variant1 (source code), by changing the GetComposite() command, which returns a Composite, to IsComposite() which returns a bool.
The GoF example (source code)
The GoF example (source code)
the cycle in the graph may be removed, in variant1 (source code), because it only exists due to the use of the Visitor pattern.
The GoF example (source code)
The GoF examples (first source code, second)
The GoF examples (source code, second)
The GoF example (source code)
The GoF example (source code) contains one cycle
which is removed, in variant1 (source code), by defining an interface for the Context class.
The GoF example (source code)
The GoF example (source code) contains one cycle
which is removed, in variant1 (source code), by defining an interface for the Widget class.
The GoF examples (first source code, second)
The GoF example (source code) contains one cycle
which is removed, in variant1 (source code), by splitting the Subject class into two so that the data, which is subject to change, is accessible from the Observer.
The GoF example (source code) contains several cycles
which are removed, in variant1 (source code), by defining
- an enumerant for the state
- a state holder which contains the objects representing the states and knows the current state
The GoF example (source code)
The GoF example (source code)
The GoF example (source code) has 4 cycles
which are removed, in variant1 (source code), by
- making ElementA and ElementB ignorant of the visitor
- splitting the visitor into an interface and an implementation