Meta-Patterns:
Design Patterns Explained.
Moisés Daniel
Díaz Toledano.
Email : moises@moisesdaniel.com
WebSite : www.moisesdaniel.com
Summary:
MetaPatterns can be
contemplated like a form of
understanding the underlying mechanisms of patterns and the form
in which they work, and even as a new patterns’ classification.
The principal objective of patterns is capturing good practices that allow us
to improve the quality of the design of systems, determining objects that
support useful roles in a specific context, encapsulating complexity, and
making it more flexible.
We can observe that the structure of these solutions (patterns) repeats, using
a series of basic mechanisms (even in different levels of abstraction) to
produce the same effects in the system.
To know these common mechanisms allows us to have a clearer vision on
patterns, as well as to have the capacity to generate them.
1.0.- Design patterns.
1.1.- Design Patterns’ Concept.
As Grady Booch said [13] "At the time- and I still believe it - I
declared patterns to be the one really refresing idea since objects entered the
scene."
Let us remember that object oriented development owes its success to the
increment of quality to the software built in this paradigm, making it more
flexible, modular, reusable and more comprehensible. In summary, elevating
their internal and external quality bench marks (both very related).
Classes and Objects gave us a new means for encapsulating abstractions,
dividing the reality and diminishing the complexity, also allowing us to base
our development efforts on inherent concepts of the problem to solve.
In this context, what have the design patterns contributed? They have
given us the possibility to organize our classes in common structures, well
proven, and modifying the system for improving its flexibility and
extensibility. In other words, increasing the easiness of adapting the software
products to the specification changes and increasing it possible reutilization.
In summary, the same benefits already made by object oriented programming,
powering the quality of the design, and therefore the software itself.
The notion of 'design pattern' existed with a lot of anteriority to
their common use in the computer community [7][6]. However it is commonly
accepted that the work that originated this discipline (in the way that we
today understand it) was the book ‘Design Patterns: Elements of Reusable
Object-Oriented Software’ writed by Gamma, Helm, Johnson, Vlissides, and knowed
generally as ‘GOF’ [8][3].
Exist numerous definitions of the term 'pattern'[1][2][8][9]. One of
them was coined by Richard Gabriel [1] and say the following : "Each
pattern is a three-part rule, which expresses a relation between a certain
context, a certain system of forces which occurs repeatedly in that context,
and a certain software configuration which allows these forces to resolve
themselves". We can also accept the following one: "A pattern
is the abstract representation of a good solution for a concrete, and generally
frequent, problem that happens in one or more contexts".
As the reader can observe, these definitions are very general due
basically to the success that has had the concept of pattern, being applied to
almost all software fields (I also have to say that before entering in the
world of the software, it was already used in certain architectural
circles[7]). This success like compensation has produced that th e concept of pattern
has become something quite diffuse, a normal situation keeping in mind that
concepts that embrace wide realities, end up in general without having real, or
precise, meaning. For all this reasons all patterns definitions have come
accompanied by a group of conditions and elements to delimite with more
accuracy the concepto of pattern.
However, the notion that have most of developers have in mind when
speaks about patterns, refers to ‘Design Patterns’, proposed initially in the
GOF [8]. This work give the following definition: “The design patterns in this book are descriptions of communicating
objects and classes that are customized to solve a general design problem in a
particular context”. Therefore, patterns appear this way centered in the
micro-structure of the applications, that is to say, their classes and objects.
For the concepts presented in this article we will use the definition
(and patterns) given in the GOF, leaving clear that however the metapattern
concept here presented can be applied in other levels of abstraction, for
example to architectural aspects of the software, etc.
In general, the patterns are structured in 'Patterns Languages ' [11],
being able to define these as: "The specification of a series of roles
(patterns) and their relationships (patterns) that allow us to describe good
solutions to the different problems that appear in a specific context."
The principal objective of design patterns is capturing good practices
that allow us to improve the quality of the design of systems, determining
objects that support useful roles in a specific context, encapsulating
complexity, and making it more flexible.
We have spoken a lot about design patterns, let us see one of them to
have a clearer image during the rest of this article:
Pattern: Strategy.
-
Intention: To define a family of
algorithms, encapsulating each one and making them interchangeable.
-
Applicability: To use when...
o
Different variants are needed of
oneself algorithm.
o
Several subclases only differs in its behavior.
o
A class defines several behaviors in multiple conditional
sentences.
-
Structure: Initially we have an
algorithm encapsulated in the class ‘ClassXYZ’, but we realize that we need to evolve toward a more flexible
structure because we must to have the possibility of applying different
algorithms in runtime.
à
à
The solution consists on taking out (decoupling) the algorithm that we
have encapsulated in the class XYZ, defining a general interface (‘AbstractAlgorithm’) for the group of algorithms
that we want to code, and encapsulating each one of these algorithms in a class
(‘Algorithm1’, ‘Algorithm2’, etc), making them interchageables.
1.2. - What makes patterns useful.
We have already said Design Patterns contribute to add flexibility and
extensibility to our designs. But in
adittion they have demonstrated to be a very successful form to reuse design,
since they not only names, abstracts and identifies the key aspects of a common
design structure that make it useful for creating a reusable object-oriented
design, but they generally are described in a specific documentary format,
making its compression and application easy for general developers.
We can say that the benefits that a pattern produce can be measured in
several senses:
§
From a the point of view of general development, the patterns contribute
to design reutilization, identifying the key aspects of a design structure that
can be applied in a big amount of situations. The importance of design
reutilization is not gratuitous, since it contribute providing us with many
advantages: decrease of the development and maintenance efforts, bigger
reliability, efficiency and consistency, and a considerable saving in
investment.
§
From the point of view of the design we can see that patterns enhance
flexibility, modularity and extensibility, internal factors closely related to
user perceived quality.
§
From the point of view of the design process, they increase our design
vocabulary, helping us to design from higher abstraction level.
If we take a look to a patter’s catalog, we will be able to see that the
structure of patterns is similar among groups of them, since its function or
objective (that is to say the effect or impact they want to take place in the
design) is similar, and this takes us to the following section.
2.0.- Meta-Patterns.
We all want to build correct, robust, expandable and reusable software.
We should be conscious that this group of external quality factors keeps a
direct relationship with the internal quality of the same one, that is to say
with its correction, flexibility, etc. However...
How do we get correction? One of the fundamental mechanisms to achieve
it, consists on reducing the inherent complexity of the problem, encapsulating
abstractions as well as normalizing and standardizing (uniforming).
How do we get flexibility? Basically adding indirection (decoupling
abstractions).
2.1.- Objective-Mechanism Diagram.
We can visualize all this in a text diagram called Objective-mechanism
Diagram and that it represents several levels of abstraction:
Diagram: - Correct Software. ·
Divide
the complexity (I simplify the problem). o
Encapsulating: Functions, classes,
components, aplicacions, systems (basically structural). How do we get the
simplicity in....? §
Functions:
functional simplicity, same semantic level in their speech. §
Code:
Notation, validation mechanisms, initialization mechanisms, mechanisms for
errors treatment, formatting the code. - Flexible-Reusable Software. ·
Adding
Indirection (decoupling). o
We
build an intermediate element (winning manipulation capacity , etc also
goes away more than the problem in itself, and it constitutes another
element to maintain). These intermediate elements can be a: §
Function.
In a principle we can understand these Objective-mechanisms like
patterns generators since they help us to create design patterns.
And, Why ‘metapatterns’ name? The 'meta’ prefix generally is used to insinuate concepts of more abstraction that those that it contemplates. For example XML, is a meta-languaje in the sense that is used to define other languages, being in turn him a language.
For this reason I will denominate them Metapatterns, passing to specify
them inside the context of the object oriented design patterns (but thet are
applicable to almost all abstraction levels).
2.2.- Meta-pattern
Encapsulator.
- Problem: We have certain functionality or complex interaction distributed
among several objects.
- Solution: To encapsulate this functionality or
interaction in an object. The encapsulador provides a new role, adding
flexibility and extensibility.
- Example problem: The creation of a complex structure of objects
(Builder).
- Original Structure and comment:
We have a group of classes that
implement a complex objects structure . The process of creating this structure
is distributed in the group of classes that form it. 
- Specific Solution :

![]()
![]()

With this solution we add flexibility and extensibility to the design,
since we isolate code for construction
and representation (the group of the classes) in the ‘Builder’ class. The
builder pattern improves modularity by encapsulating the way a complex object
is constructed and represented.
- Abstract Representation: It’s a class.

à à

- Some patterns that implement it:
§
Builder. Encapsulate creational functionality (originally distributed)
in a class. Separate the construction of a complex object from its
representation so that the same construction process can create different
representations.
§
Facade. Encapsulate the interfaces of a subsisten providing a unified
interface, a single access point.
§
Mediator. Encapsulates how a set of objects interact in a class
(‘Mediator’). Mediator promotes loose cooupling by keeping objects from
referring to each other explicitly, and it lets you vary ther interaction
independently.
2.3.- Meta-Pattern Adder.
- Problem: We have a class to which we want to add (or modify)
certain functionality.
- Solution: We add another class in which we encapsulate this
functionality. The Adder provides new functionality to the system through a new
role that makes of mediator.
- Example Problem: ‘Client B’ want to use an existing class
‘ClassXYZ’, and its interface does not match the one you need:
- Original Structure:

- Specific Solution:

We add a class (called ‘Adapter’) that encapsulates a new interface in
such a way that the ‘class B’ can use the functionality (total or partial) that
implements ‘claseXYZ’.
- Abstract Representation: ‘New Funcionality’ is the adder class.

With Polimorphism:

- Some patterns that implement it:
§
Adapter. Add a new interface converting the interface of a class into
another interface clients expect. Adapter lets classes work toghether that
couldn’t otherwise because of incompatible interfaces.
§
Command. Add sophisticated control about method exection encapsulating a
request as an object, thereby letting you parameterize clients with different
requests, queue or log requests, and support undoable operations.
§
Proxy. Add access control to an object providing a surrogate or
placeholder for another object.
2.4.- Meta-Pattern Decoupler.
- Problem: We have a complex functionality inside a class, and we
want to add flexibility.
- Solution: We can encapsulate this functionality in a aggregated
(added) class to the original one. The Decoupler already provides flexibility
to some functionality existent through a new role.
- Example Problem: We need different algorithms because they will
be appropiate at different times. We have ClassXYZ that implements
‘Algorithm()’ and must be able to implements more algorithms.
- Original Structure:

- Specific Solution:

We declare an common interface (‘AbstractAlgorithm’) to group all algorithms
that we are going to implement (‘Algorithm1’, …., ‘Algorithm N’) , and
subclassify each one from the interface.
- Abstract Representation:

With Polimorphism:

- Some patterns that implement it:
§
Bridge. Decouple an abstraction from its implementation so that the two
can vary independently. So decouple implementation.
§
State. Allow an object to alter its behaviour when its internal state
changes. The object will appear to change its class. Decouple object state
(behaviour).
§
Strategy. Define a family of algorithms, encapsulate each one, and make
them interchangeable. Strategy lets the algorithm vary independently from
clients that use it. Decouple algorithms.
2.5.- What makes metapatterns useful.
Basically, Metapatterns:
§
Communicate design notions and quality.
§
Help us to classify patterns.
§
Provide us a form of understanding patterns from a conscious and
rational perspective, not from inspiration. That is to say we can see design
patterns like perfectly rational and natural solutions to the problems that
solve eliminating part of their magic and the sensation that they are
discovered, and not invented elements. They are the result of applying rational
principles very well established.
§
Helps us to generate new patterns. The book of the GOF presented a group
of very defined and useful patterns that have had a lot of resonance in the
world of software development. But it is necessary to say that they are not the
only ones existent, and that continually are developed new design patterns. We
are inmersed in a changing world, with continuous changing technological
realities. In these new contexts it will go arising new patterns. Metapatterns
will help us to generate them.
§
Help us to design from higher abstraction level.
We can give a very interesting example of what means the last point.
“Aspect-Oriented programming (AOP) is the
lastest methodology to support a new unit of software modularity: aspects.
Aspects are elemnents such as security policies and synchronization,
optimization, communication or integrity rules that crosscut traditional module
boundaries.
At design time, a typical AOP scenario separates aspects from the classes and
methods that make up application components”. We can see the a AOP like the
extensive use of the decoupler metapattern regarding a series of specific aspects and applied to all the
classes of an application.
In the following section I present some design patterns generated in a
very simple way using the meta-pattern concept.
3.0.- Some example patterns.
With the meta-pattern concept it is not only easier to understand the
design patterns but generating them in our designs.
Here I describe some patterns direct consequence of the meta-pattern
concept.
3.1.- Validator.
·
Problem: We have an object that has to make complex validations with the
arguments that receives and on the objects with it is related.
3.2.- Persistor (persistence)
·
Problem: We have implemented inside a class their file persistence, and
we need bigger flexibility (persistence in local databases, remote, etc).
3.3.- Set.
·
Problem: We have a great collection of objects (generally of the same
type) and we have to enable a simple way to provide information about them.
3.4.- Logger.
·
Problem: We want to have a detailed registration of how the system works,
with what we obtain a structure in which the role of maintaining a registration
of the operation of the system is distributed among all objects.
References:
·
[1] Pattern Definition Thread (http://c2.com/cgi/wiki?PatternDefinionThread , http://c2.com/cgi/wiki?MorePatternDefinionThread)