GoFRefactored
GoFRefactored copied to clipboard
Examples from GoF book and refactorings
Dependencies in the Gang of Four examples
Abstract
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.
Introduction
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
Creational Patterns
AbstractFactory
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.
Builder
The GoF example (source code)
FactoryMethod
The GoF example (source code)
Prototype
The GoF example (source code)
Singleton
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)
Structural Patterns
Adapter
The GoF example (source code)
Bridge
The GoF example (source code)
Composite
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.
Decorator
The GoF example (source code)
Facade
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.
Flyweight
The GoF example (source code)
Proxy
The GoF examples (first source code, second)
Behavioural Patterns
ChainOfResponsibility
The GoF examples (source code, second)
Command
The GoF example (source code)
Interpreter
The GoF example (source code) contains one cycle
which is removed, in variant1 (source code), by defining an interface for the Context class.
Iterator
The GoF example (source code)
Mediator
The GoF example (source code) contains one cycle
which is removed, in variant1 (source code), by defining an interface for the Widget class.
Memento
The GoF examples (first source code, second)
Observer
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.
State
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
Strategy
The GoF example (source code)
TemplateMethod
The GoF example (source code)
Visitor
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