Design Patterns by Gamma, et al.

The example C++ code from the GoF (Gang of Four) book Design Patterns has had its dependencies analysed.

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

A DeepEnds coupling analysis 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

AbstractFactory

The GoF example 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.

GoF

Builder

The GoF example

GoF

FactoryMethod

The GoF example

GoF

Prototype

The GoF example

GoF

Singleton

The GoF examples

GoF

GoF2

GoF3

the cycle in the last graph may be removed by inserting an interface as shown in variant1

Variant1

Structural Patterns

Adapter

The GoF example

GoF

Bridge

The GoF example

GoF

Composite

The GoF examples

GoF

GoF2

the cycle in the first graph may be removed, in variant1, by changing the GetComposite() command, which returns a Composite, to IsComposite() which returns a bool.

Variant1

Decorator

The GoF example

GoF

Facade

The GoF example

GoF

the cycle in the graph may be removed, in variant1, because it only exists due to the use of the Visitor pattern.

Variant1

Flyweight

The GoF example

GoF

Proxy

The GoF examples

GoF

GoF2

Behavioural Patterns

ChainOfResponsibility

The GoF examples

GoF

GoF2

Command

The GoF example

GoF

Interpreter

The GoF example contains one cycle

GoF

which is removed, in variant1, by defining an interface for the Context class.

Variant1

Iterator

The GoF example

GoF

Mediator

The GoF example contains one cycle

GoF

which is removed, in variant1, by defining an interface for the Widget class.

Variant1

Memento

The GoF examples

GoF

GoF2

Observer

The GoF example contains one cycle

GoF

which is removed, in variant1, by splitting the Subject class into two so that the data, which is subject to change, is accessible from the Observer.

Variant1

State

The GoF example contains several cycles

GoF

which are removed, in variant1, by defining

Variant1

Strategy

The GoF example

GoF

TemplateMethod

The GoF example

GoF

Visitor

The GoF example has 4 cycles

GoF

which are removed, in variant1, by

Variant1