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.

      • Classes: identificative unicity, avoiding semantic difference (methods that treat similar abstractions, relationships of similar abstract level...).
      • ......
    • Standardization - Normalization (basically is functional).

§         Code: Notation, validation mechanisms, initialization mechanisms, mechanisms for errors treatment, formatting the code.

      • Levels of uniform abstraction in the speeches (programming).
      • Interaction Mechanisms (also visualization). ).
      • Communication Mechanisms among entities of similar levels of abstraction. I use the same ones 'methods' to make the same things (components, etc). ).

- 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.

      • Class.
      • Classes + Polimorphism.
      • Component.
      • Subsystem.
      • Etc...
 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


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)