The purpose of this document is not to describe individual patterns in great detail, nor is it any kind of tutorial. It is simply to give an overview of some of the various patterns that are available and to give my personal views on their implementation. As this section of my website is devoted to building web applications with PHP I shall concentrate on those patterns which can be readily applied to this environment.

What exactly are patterns? Patterns are supposed to help you build on the collective experience of skilled software engineers. They capture existing, well-proven experience in software development and help to promote good design practise. Every pattern deals with a specific, recurring problem in the design or implementation of a software system. Patterns can be said to exhibit the following properties:

A pattern addresses a recurring design problem that arises in specific design situations and presents a solution to it.

Patterns document existing, well-proven design experience.

Patterns identify and specify abstractions that are above the level of single classes and instances, or of components.

Patterns provide a common vocabulary and understanding for design principles.

Patterns are a means of documenting software architectures.

Patterns support the construction of software with defined properties.

Patterns help you build complex and heterogeneous software architectures.

a technique for making code more flexible by making it meet certain criteria

a design or implementation structure that achieves a particular purpose

a high-level programming idiom

shorthand for describing certain aspects of program organization

connections among program components

the shape of an object diagram or object model

This provides us with the following definition:

A pattern for software architecture describes a particular recurring design problem that arises in specific design contexts, and presents a well-proven generic scheme for its solution. The solution scheme is specified by describing its constituent components, their responsibilities and relationships, and the ways in which they collaborate.

In general a pattern has four essential elements:

The pattern name is a handle we can use to describe a design problem, its solutions and consequences in a word or two. Naming a pattern immediately increases our design vocabulary. It lets us design at a higher level of abstraction. Having a vocabulary for patterns lets us talk about them with our colleagues in our documentation, and even to ourselves. It makes it easier to think about designs and to communicate them and their trade-offs to others. Finding good names is one of the hardest parts of developing a catalog.

The problem describes when to apply the pattern. It explains the problem and its context. It might describe specific design problems such as how to represent algorithms as objects. It might describe class or object structures that are symptomatic of an inflexible design. Sometimes the problem will include a list of conditions that must be met before it makes sense to apply the pattern.

The solution describes the elements that make up the design, their relationships, responsibilities and collaborations. The solution does not describe a particular concrete design or implementation because a pattern is like a template that can be applied in many different situations. Instead the pattern provides an abstract description of a design problem and how a general arrangement of elements classes and objects in our case) solves it.

The consequence are the results or trade-offs of applying the pattern. Though consequences are often unspoken when we describe design decisions, they are critical for evaluating design alternatives and for understanding the costs and benefits of applying the pattern.

The consequences for software often concern space and time trade-offs. They may address language and implementation issues as well. Since reuse is often a factor in object-oriented design,the consequences of a pattern include its impact on a system's flexibility, extensibility or portability. Listing these consequences explicitly helps you understand and evaluate them.

The accepted definition of design patterns goes something like this:

A pattern provides a solution schema rather than a fully-specified artifact or blueprint. You should be able to reuse the solution in many different implementations, but in a way that its essence is still retained. A pattern is a mental building block. After applying a pattern an architecture should include a particular structure that provides for the role specified by the pattern, but adjusted and tailored to the specific needs of the problem at hand. No two implementations of a given pattern are likely to be the same. It is also possible for a particular pattern to have several variants to cater for different circumstances.

In software engineering, a design pattern is a general reusable solution to a commonly occurring problem within a given context in software design. A design pattern is not a finished design that can be transformed directly into source or machine code. It is a description or template for how to solve a problem that can be used in many different situations. Patterns are formalized best practices that the programmer must implement themselves in the application.

That is the problem I have with design patterns - they provide descriptions of solutions instead of working code which can either be generated, copied or otherwise reused. They are vague and wishy-washy, without substance, and can be interpreted and implemented in many ways. If something is open to interpretation it is also open to over-interpretation and mis-interpretation. If something can be used it can also be mis-used. If no sample implementation is provided then there is no guarantee that a particular implementation will be effective. In the real world a pattern offers some sort of saving when used to make copies of an original, with each copy taking less time to build than the original. But if each implementation of a design pattern is unique and takes just as much time to build as the original, then where is the saving? Where is the reusability? It is not possible to write a code template for a design pattern and to generate implementations of that pattern from that template, so where is the saving, where is the reusability?

It should also be pointed out that attempting to use a design pattern may not provide beneficial results if the implementation is faulty. A language may provide several different ways of achieving a particular result, so the merits of each need to be examined against the context of the problem in hand - one may be faster, but another may be more extensible or easier to maintain.

You should also be aware that some of these patterns were designed with object-oriented programming languages in mind, so attempting to employ them with a non-OO language may not yield the results you expect. Some of them were designed to deal with the way in which a particular language works (such as a compiled language), so may be totally unnecessary in another language (such as a scripting language).

Viable software architectures are built according to some overall structuring principle. These principles are described as architectural patterns. An architectural pattern expresses a fundamental structural organisation schema for software systems. It provides a set of predefined subsystems, specifies their responsibilities, and includes rules and guidelines for organising the relationships between them.

The Model-View-Controller (MVC) architectural pattern divides an interactive application into three components. It was originally developed to map the traditional input, processing and output roles into the GUI realm:

Input --> Processing --> Output
Controller --> Model --> View

The model contains the core functionality and data. It is independent of specific output representations or input behaviour.

The view displays information to the user. A view obtains data from the model. There can be multiple views of the model.

The controller handles user input and calls operations on the Model, then hands the result to the View.

Views and controllers together provide the user interface.

The model, view and controller are intimately related and in constant contact. Therefore, they must reference each other. The picture below illustrates the basic Model-View-Controller relationship:

Figure 1 - The basic MVC relationship

The purpose of the MVC pattern is to separate the model from the view so that changes to the view can be implemented, or even additional views created, without having to refactor the model. Note that the model may or may not reference a persistent data store (database).

Note that although this pattern only shows three components it is possible to divide any one of them into smaller sub-components.

Some say that in a client/server context it is 'client + application + database'.

Some say that in a web context it is 'web browser + web application + database'.

Some say that it is three layers of hardware, as in 'web server + application server + database server'.

Taking the last one first, although it is possible to physically deploy a software application over three layers of hardware, you must have divided the application code into three layers of software to begin with so that you actually have something that can occupy each piece of hardware. The former is known as physical 3-tier while the latter is known as logical 3-tier. It should be possible for a logical 3-tier application to be deployed on a single physical device as well as several devices. As hardware issues are outside the scope of this document I shall confine myself to logical 3-tier.

The first time I read about the 3-tier architecture was in 1999, and it is that description that I shall use in this document. It identified the following areas of logic:

Business logic - the processing of business rules and task-specific behaviour.

Data Access logic - communicating with the physical database using the APIs provided by that database engine.

These areas are also referred to as layers or tiers.

This pattern can be represented in the following diagram:

Figure 2 - The 3-Tier Architecture

The presentation layer never talks to the data access layer directly - it talks only to the business layer. The business layer receives requests from the presentation layer, which may be:

Requests to read data, in which case the business layer may instruct the data access layer to obtain the data from the database. Note that a single request may not be limited to a single database table, or even a single I/O statement.

Requests to write data, in which case the business layer will apply the relevant validation rules before instructing the data access layer to update the database. Note that a single request may not be limited to a single database table, or even a single I/O statement.

Among the advantages of separating the application logic in this manner are:

Maximises code reuse and minimises code duplication. For example, each business entity has a single component in the business layer, and all presentation layer components which want to access this business entity go through the same business layer component.

It is possible to modify the application by making changes to just one tier, leaving the other two unaffected by the change. For example:

It should be possible to change the presentation layer, such as from client/server to the web, without affecting the business or data access layers.

It should be possible to change the business rules for an entity without affecting the presentation or data access layers.

It should be possible to change the data access layer, such as switching from one database engine to another, without affecting the presentation and business layers.

As each tier is now independent of the other it becomes possible to use different sets of developers, with different skill sets, for each tier. This may reduce the need for multi-skilled developers. For example, you may have HTML/CSS/JavaScript developers for the presentation layer, and Java/PHP/ASP/whatever developers for the business layer, and SQL wizards for the data access layer.

Note that with this pattern you are not restricted to a single component within each layer. You can divide each layer into as many sub-layers as you wish.

The subsystems of a software architecture, as well as the relationships between them, usually consist of several smaller architectural units. These units are described using design patterns. A design pattern provides a scheme for refining the subsystems or components of a software system, or the relationships between them. It describes a commonly-recurring structure of communicating components that solves a general design problem within a particular context. Design pattern address the sort of problems typically encountered after the overall structure of a software system has been specified.

An important property of all design patterns is that they are independent of a particular application domain. They deal with the structuring of application functionality, not with the implementation of the application functionality itself.

Below are standard descriptions of some common design patterns, which, if implemented properly, should give beneficial results. This is fine in theory, but in practice the results may not be as good as you expect.

The Adapter design pattern provides a way for a client to use an object whose interface is different from the one expected by the client, without having to modify either. The Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.

This pattern is suitable for solving issues that arise, for example, when:

You want to replace one class with another and the interfaces do not match.

you want to create a class that can interact with other classes without knowing their interfaces at design time.

The Bridge design pattern decouples an abstraction from an implementation so that the two can vary independently.

When an abstraction can have one of several possible implementations, the usual way to accommodate them is to use inheritance. An abstract class defines the interface to the abstraction, and concrete subclasses implement it in different ways. But this approach is not always flexible enough. Inheritance binds an implementation to the abstraction permanently, which makes it difficult to modify, extend, and reuse abstractions and implementations independently.

The Client-Dispatcher-Server design pattern introduces an intermediate layer between clients and servers, the dispatcher component. It provides location transparency by means of a name service, and hides the details of the establishment of the communication connection between clients and servers.

An example of this pattern would be an information retrieval system where the information providers are both on a local network and distributed over the world. To access an individual information provider it is necessary to specify its location and the service to be executed. When an information provider receives a request from a client application it runs the appropriate service and returns the requested information to the client.

The Command Processor design pattern separates the request for a service from its execution. A command processor component manages requests as separate objects, schedules their execution, and provides additional services such as the storing of request objects for later undo.

An example of this pattern would be a text editor which provides a way to deal with mistakes made by the user. A simple implementation would be to undo the most recent change, but a more attractive solution may be enable the undoing of multiple changes.

The DAO design pattern allows data access mechanisms to change independently of the code that uses the data. The Data Access Object manages the connection with the data source to obtain and store data.

An example of this design pattern is where an application might be deployed with a variety of database engines and where each of these engines has its own set of APIs. If all these APIs were to be isolated within a single object, one object per database engine, then switching from one database to another would be as simple as switching from one DAO to another.

Another variation is where the data may come from a variety of differences sources, such as DBMS, LDAP, XML repository, et cetera. By routing all access through a DAO the client need not be concerned about the physical location of the data, or which APIs to use in order to access it.

The Radicore framework contains an implementation of the DAO in the form of a DML Class.

Sometimes we want to add responsibilities to individual objects, not to an entire class. A graphical user interface toolkit, for example, should let you add properties like borders or behaviors like scrolling to any user interface component. One way to add responsibilities is with inheritance. Inheriting a border from another class puts a border around every subclass instance. A more flexible approach is to enclose the component in another object that adds the border. The enclosing object is called a decorator.

The Dependency Injection pattern (also known as Inversion of Control) manages the dependencies between objects by creating the dependent objects outside the object which uses that dependency. In other words instead of objects configuring themselves they are configured by an external entity.

If Object A calls Object B, then A is dependent on B. The usual method is to allow Object A to instantiate Object B just before it needs to use it, but this design pattern allows an instance of Object B to be created independently of Object A so it can be "injected" into Object A.

The Factory Method design pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate. The Factory Method lets a class defer instantiation to subclasses.

An example of this pattern would be a class to read image files and make thumbnails out of them, where each type of image file (.gif, .jpg, .png, .tif, et cetera) would require different code. It would be possible to put all the code into a single class, as shown in the following code snippet:

This method has the advantage of abstracting the file type from the class that calls this ImageReader, but as the number of file types supported gets larger, the code will quickly become huge, unwieldy and hard to maintain. A much better method would be to extract the code for each file type and put it into a class of its own, as shown in the following code snippet:

The Forwarder-Receiver design pattern provides transparent inter-process communication for software systems with a peer-to-peer interaction model. It introduces forwarders and receivers to decouple peers from the underlying communication mechanism.

Distributed peers collaborate to solve a particular problem. A peer may act as a client, requesting services, as a server, providing services, or both. The details of the underlying inter-process communication mechanism for sending or receiving messages (such as TCP/IP, sockets or message queues) are hidden from the peers by encapsulating all system-specific functionality into separate components. Examples of such functionality are the mapping of names to physical locations, the establishment of communication channels, or the marshaling and unmarshaling of messages.

The Front Controller design pattern defines a single component that is responsible for processing application requests. A front controller centralizes functions such as view selection, security, and templating, and applies them consistently across all pages or views. Consequently, when the behavior of these functions need to change, only a small part of the application needs to be changed: the controller and its helper classes.

This may be useful in interactive Web applications which are composed of brittle collections of interdependent Web pages as such applications may be hard to maintain and extend.

The Iterator design pattern provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation. This is useful if an aggregate can exist in several possible forms.

Depending on the form of the aggregate in question, the actual instructions required to navigate through the aggregation may vary. This means that the client code must know which form of aggregate is being used so that it can issue the correct instruction. The Iterator pattern bypasses this requirement by allowing the client to use standard commands, such as NEXT or PREVIOUS, with the Iterator then taking the responsibility of issuing the correct command for that form of aggregate.

The Master-Slave design pattern supports fault tolerance, parallel computation and computational accuracy. A master component distributes work to identical slave components and computes a final result from the results these slaves return.

An example of this pattern would be the travelling salesman problem, which is well known in graph theory. The task is to find an optimal round trip between a given set of locations, such as the shortest trip that visits each location only once. The solution involves identifying a number of possibilities, then creating a slave component for each of these possibilities. The master component can then examine the results from each of the slaves in order to pick out the best one.

The Observer (or Publisher-Subscriber) design pattern helps to keep the state of cooperating components synchronised. To achieve this it enables one-way propagation of changes; one publisher notifies any number of subscribers about changes to its state.

One dedicated component takes the role of the publisher. All components dependent on changes in the publisher are its subscribers. The publisher maintains a registry of currently-subscribed components. Whenever a component wants to become a subscriber, it uses the subscribe interface offered by the publisher. Analogously, it can unsubscribe. Whenever the publisher changes state, it sends a notification to all its subscribers. The subscribers in turn retrieve the changed data at their discretion.

The Proxy design pattern makes the clients of a component communicate with a representative rather than to the component itself. Introducing such a placeholder can serve many purposes, including enhanced efficiency, easier access and protection from unauthorised access.

The generic Proxy pattern can have such variants as:

Remote Proxy - where clients of remote components should be shielded from network addresses and inter-process communication protocols.

Protection Proxy - where components must be protected from unauthorised access.

Cache Proxy - where multiple local clients can share results from remote components.

Synchronisation Proxy - where multiple simultaneous access to a component must be synchronised.

Counting Proxy - where accidental deletion of components must be prevented, or usage statistics collected.

Virtual Proxy - where the processing or loading of a component might be costly, while partial information about the component might be sufficient.

Firewall Proxy - where local clients should be protected from the outside world.

The Singleton design pattern ensures that a class only has one instance, and provides a single point of access to it.

A global variable could be used, but although it does make the object accessible it does not keep you from instantiating multiple objects. A better solution is to make the class itself responsible for keeping track of its sole instance. The class can ensure that no other instance can be created by intercepting requests to create new objects, and it can provide a way to access the instance.

The Radicore framework contains an implementation of the Singleton pattern. This implementation avoids all those problems that other people have found, which is why I claim that Singletons are NOT evil.

The Strategy design pattern defines a set of algorithms, encapsulates each one, and makes them interchangeable. The Strategy pattern lets the algorithm vary independently from clients that use it.

There are several advantages to doing this. First, if you have several different behaviours that you want an object to perform, it is much simpler to keep track of them if each behaviour is a separate class, and not buried in the body of some method. Should you ever want to add, remove, or change any of the behaviours, it is a much simpler task, since each one is its own class. Each such behaviour or algorithm encapsulated into its own class is called a Strategy.

The View Handler design pattern helps to manage all views that a software system provides. A view handler component allows clients to open, manipulate and dispose of views. It also coordinates dependencies between views and organises their update.

An example of this pattern would be a multi-document editor which allows several documents to be worked on simultaneously. Each document is displayed in its own window. To use such editors effectively users need support for handling the windows. For example, they might want to clone a window to work with several independent views of the same document. User also often do not close open windows before quitting the editor, so it is the task of the editor to keep track of all open documents and close them carefully. Changes in one window may affect other windows as well, so there is a need for an efficient update mechanism for propagating changes between windows.

The Whole-Part design pattern helps with the aggregation of components that together form a semantic unit. An aggregate component, the Whole, encapsulates it constituent components, the Parts, organises their collaboration, and provides a common interface to its functionality. Direct access to the Parts is not possible.

An example of this pattern would be a computer-aided design (CAD) system for 2-D and 3-D modelling which allows engineers to design graphical objects interactively. In such systems most graphical objects are modelled as compositions of other objects. For example, a car object aggregates several smaller objects such as wheels and windows, which themselves may be composed of even smaller objects such as such as circles and polygons. It is the responsibility of the car object to implement functionality that operates on the car as a whole, such as rotating or drawing.

Idioms deal with the implementation of particular design issues. An idiom is a low-level pattern specific to a particular programming language. An idiom describes how to implement particular aspects of components or the relationships between them using the features of the given language.

Idioms represent the lowest-level patterns. They address aspects of both design and implementation. Most idioms are language-specific - they capture existing programming experience. Often the same idiom looks different in different languages, and sometimes an idiom that is useful for one programming language does not make sense to another. For example, the C++ community uses reference counting idioms to manage dynamically allocated resources, while Smalltalk provides a garbage collection mechanism and therefore has no need for such idioms.

Idioms can also address low-level problems related to the use of a language, such as the naming of program elements, the formatting of source text or the choice of return values. Such idioms approach or overlap areas that are typically addressed by programming guidelines. A collection of related idioms defines a programming style. Idioms demonstrate competent use of programming language features, and can therefore also support the teaching of a programming language. They also ease communication among developers and speed up software development and maintenance.

As this is such a huge topic and very much language-independent I shall not delve into any details.

My biggest criticism of design patterns is that the are not proper patterns, just descriptions or outlines of possible patterns. The dictionary definition for "pattern" contains the following:

A design, plan, model, etc., from which a thing is to be made.

An original to be imitated, an exemplar, a model.

Knitting patterns and sewing patterns are examples of "real" patterns. They are blueprints from which copies can be made. When the original is constructed a lot of effort goes into the making of the pattern so that less effort is required when making each copy.

The authors of design patterns state quite openly that a design pattern is not a template or blueprint, it is just the description of a possible solution which you have to implement yourself. But how useful is that? Are there any actual savings to be made by using design patterns as against not using them? Software development requires program code, yet the implementation of design patterns does not seem to involve the generation of reusable code. This means that different implementations of the same pattern do not have any common code which can be shared, therefore each implementation has to be crafted by hand. If patterns are supposed to provide some element of reusability so that subsequent implementations can be produced with less effort than the first, then where is this reusability provided with design patterns?

I am not the only one to notice this anomaly. The following statement can be found in PatternBacklash:

In software engineering, duplication of something is often considered a sign that more abstraction or factoring is needed. Duplication should generally be refactored into one or fewer spots to simplify the code and localize changes to one or fewer spots. In other words, why do patterns have to be duplicated instead of just referenced for each usage? Do GOF patterns represent unnecessary duplication?

Compare design patterns with a Painting By Numbers kit. In the kit you get sheets of paper on which there are collections of shapes, each containing a number, and a collection of colours which are numbered. All the budding artist has to do is put the right color into each shape and the result is guaranteed. With design patterns you don't get pre-drawn shapes and numbered colours, you simply get descriptions of shapes and colours. The budding artist then has to pick his own shapes and his own colours. How useful is that?

I have never heard of any tool which allows a fully fledged component to be created simply by saying "combine design pattern X with object Y and generate component Z", and this just proves to me that there is very little of any design pattern which can actually be reused - it may describe an outline of a solution, but you still have to build every part of that solution by hand. To circumvent this limitation you need a different sort of pattern altogether, which is where Transaction Patterns distinguish themselves. They are "real" patterns insofar as code templates actually exist, which enables working components to be created simply by saying "combine transaction pattern X with object Y and generate component Z". Most of the component logic is inherited or imported from the original pattern definition, so there is little or nothing left over which has to be crafted by hand. This provides a much higher level of reusability than can ever be obtained from design patterns.

Some people say that design patterns are nothing more than a common language that programmers can use among themselves when discussing their solutions, but this notion falls down on several points:

The same pattern can have different names depending on which book you use as your pattern "bible".

The same problem can be solved by a variety of different patterns.

A pattern can have any number of different implementations.

This means that you can talk to a group of programmers about design patterns and they will begin arguing about their names, which patterns to use to solve a particular problem, and whose implementation is the most "pure" or "correct". Therefore it is safe to say that patterns do not provide a common language which is universally accepted - they are just a source of yet another set of religious arguments.

Although I agree that design patterns have their place (I have to say that as I have used and actively promoted some of them), I do not believe that slavishly following a set of design patterns is necessarily beneficial, just as I do not believe that slavishly following the OO paradigm is the only way to write effective programs. A good design will always be better than a bad design, a normalised database will always perform better than an un-normalised database, structured code will always be easier to maintain that unstructured code, and good procedural code will always be better than bad OO code. So where is the benefit from using design patterns? In my experience all the successful projects on which I worked were not centered around design patterns, yet the one project which was an abject failure was specifically designed to use the architect's favourite set of patterns. So using design patterns can contribute to the failure of a project, and not using design patterns can contribute to the success of a project.

Some of those design patterns have little relevance with PHP. For example, the iterator pattern is hardly relevant as PHP does not have a wide selection of aggregations - it just has arrays. I have heard some people say that the process of pagination in a web page is a prime example of the iterator pattern, therefore it should be implemented in a single class. This is utter nonsense. Pagination requires some processing in each of the presentation, business and data access layers, therefore it cannot be implemented in a single object. See How do you deal with pagination? for details. Some people also say that a database result set is a prime candidate for an iterator object because each DBMS has its own APIs to move through that result set. In my infrastructure the Data Access Object automatically converts the result set into an array before any data is passed back, so any potential problem no longer exists.

Patterns which allow an object to keep multiple views synchronised, such as the observer and view handler patterns, are hardly relevant in a web environment as there is only ever a single view at any one time - the web page (HTML document). If I want the data output in a different format, such as PDF or CSV, then I use a different view object in a different transaction.

I have successfully implemented the 3-Tier architecture in two different languages (UNIFACE and PHP), and have implemented the Model-View-Controller design pattern in PHP. I must warn you though that my implementations are totally unique and are not considered to be 'politically correct' in some circles. See below for details.

Some other people seem to think that it is impossible to implement the 3-Tier architecture in a language that is not object-oriented, but that is complete hogwash. How do I know? Because I have done it.

For many years as a COBOL programmer I was used to developing in a 1-tier architecture where presentation, business and data access logic coexisted within the same program. Then in the early 1990s I switched to a non-OO 4th Generation Language (4GL) called UNIFACE where all data access was performed through an interchangeable database driver. The components we developed consisted of nothing more than presentation and business logic, which made it a 2-tier architecture. There was no easy method of separating these two areas of logic as the methods available to transmit the data between a presentation component and a business component were extremely primitive. Compared with PHP the array processing in UNIFACE is like something out of the stone age. An attempt was made to address this shortcoming in version 7.2.04 when the language authors implemented a type of component for the business layer known as an Object Service. I tried using this within my test environment, but the results were less than satisfactory.

Then in 1999 I was head hunted by a company who were trying to build a new application in UNIFACE using the 3-tier architecture. I was supposedly recruited because of my experience, especially with the creation of development infrastructures, but when I joined the team they promptly ignored everything I had to say. The members of the team were a motley crew:

Two contractors who knew UNIFACE version 6 but had never used version 7.

Two graduates fresh out of university who thought they knew everything but in fact knew nothing that was usable.

Two consultants from UNIFACE who knew the internals of the language (their background was in C and C++), but who had never actually used it to develop real-world applications.

These six 'experts' spent six months in developing a 3-tier infrastructure that they thought was the best thing since sliced bread. Their design incorporated all the right patterns such as 'controller', 'decorator', 'facade', 'bridge', 'view', 'translator', 'presentation object', 'business object' and 'data access object', so what could possibly go wrong? To quote a famous doctor: The operation was a success, but the patient died. I had warned them beforehand that in my not-so-humble opinion their infrastructure was far too complicated and far too cumbersome and was doomed to failure, but they refused to listen. After all, they were 'experts' and they 'knew best'. What was blindingly obvious to me suddenly became visible to them when it came to build the first live transactions using this infrastructure - the process took far, far longer than they had scheduled. The first two screens to be built were a LIST screen and a SEARCH screen, and it took -- wait for it -- two developers a total of 10 days. With a bit of fine tuning they managed to get it down to one developer for 10 days, but that was the best they could do. When these times were extrapolated across the remainder of the system they suddenly became aware that the project would be 6 months overdue and £2 million over budget. When these figures were relayed to the client he took the first sensible decision in the history of the project - he cancelled it on the spot.

The development team was disbanded, so I was sent back to my company's local office. While waiting for reassignment I decided to update my personal development environment from 2-tier to 3-tier and to replicate those first two live screens. I was so successful that within 2 weeks not only had I got the LIST and SEARCH screens working, but also the INSERT, UPDATE, ENQUIRE and DELETE screens as well. So what those 'experts' had failed to achieve in 3 man-years I managed to polish off in 2 man-weeks. I informed them of my success, but was told your results don't count as your methods are wrong. Not wishing to continue life as a proctologist (someone who works with a***holes) I quit.

How was it that my efforts were a success while theirs were an abject failure? Perhaps it was a total difference in attitude:

Their approach was dogmatic:

They were rules oriented - they followed a particular set of rules with almost religious fanaticism, and assumed that the results, whatever they were, had to be acceptable.

They believed that you first picked out a selection of design patterns, then made the language conform to those patterns without investigating whether they would help or hinder the solution.

They did not have an in-depth knowledge of the strengths and weaknesses of the language, therefore had no idea of what patterns could be used nor how best to implement them.

They believed that object-oriented methods were the way to go, so they tried to bend the language to their will.

I am results oriented - I aim to produce the best results that I can, and to achieve this aim I will adopt or reject any methodology that I see fit.

I first wrote code that worked, then looked for design patterns that could be applied without interfering with those results.

I had used the language for six years, and as soon as version 7 was released I had converted my personal development environment to take advantage of the new features. I therefore had a better idea of what patterns could be applied, and the best way to apply them.

I knew that trying to apply OO techniques to a non-OO language would not be productive. Common sense should tell anyone that trying to force a language to act in a way contrary to its design principles is like trying to push a piece of string - better in theory than in practice.

After having used a successful implementation of the 3-Tier architecture to develop components I could definitely see the benefits, so when I began developing in PHP I sought a similar architecture. Because there was nothing pre-existing that satisfied my requirements I decided to build my own. My implementation is documented in A Development Infrastructure for PHP.

Identify the HTTP GET/POST request in order to activate the relevant method on the specified database object.

Extract all data from the database object and construct an XML document.

Activate an XSL transformation using this XML document and the specified XSL stylesheet to produce the HTML output.

The advantage of using XSL transformations to build all HTML output is that all the logic for building each web page is entirely separate from the logic which obtains the data to go into that web page. When a colleague looked at my code he remarked that it was a perfect example of the MVC design pattern. At first I disbelieved him because I had seen samples of code used to implement this pattern, and my code was completely different. Then I did some research to discover the principles of the MVC design pattern rather than the details of particular implementations, and I discovered that my code did in fact follow those principles quite closely. I had separate components which could definitely be identified as being part of either the Model, the View or the Controller.

Following a set of principles by inventing my own implementations is nothing new to me. When I documented my method of using classes to access database tables I received a lot of criticism from self-styled OO purists who said your implementation is wrong, real OO programmers don't do it that way. I found their arguments quite amusing, so I put them all, along with my responses, in a document entitled What is/is not considered to be good OO programming.

Architectural patterns which provide a framework to contain all the transactions within an application.

Design patterns which may be combined to build individual transactions.

While many people regard design patterns as the ultimate in building blocks for application development, for me they are entirely the wrong level of abstraction as they provide very little in the way of reusable code. A design pattern may describe an outline of a solution, but you still have to build every part of that solution by hand. It may be acceptable to describe an application framework in terms of the design patterns which it uses, but when describing the application transactions which are built on top of that framework I have found that a totally different vocabulary is needed.

A typical CRUD application is made up of a number of different user transactions (application components), each of which has a user interface (UI, page, screen) which allows the user to perform some operation (Create/Read/Update/Delete) on one or more tables in the application database. When describing a transaction to a user, and to the programmer who will build it, it is simply a case of "this is what it looks like and this is what it does", and not "these are the design patterns which it uses".

Although each transaction is different, after having built a number of transactions it may be possible to spot some similarities between one transaction and another. Take the following situation:

Transaction #1 does something to database table 'A'.

Transaction #2 does exactly the same thing, but to database table 'B'.

That phrase "does exactly the same thing" should trigger in your mind that there is something in common between these two transactions, and you should immediately be asking yourself "how much of the code in transaction #1 can I reuse in transaction #2?" An inexperienced programmer may say that very little is reusable because each piece of code has a different set of object names hard-coded into it, but a wiser programmer will be able to see where that code can be converted into a subroutine which will accept a list of object names as parameters. That single subroutine can then be referenced any number of times with different lists to carry out that common processing on different objects.

Rather than look at the inside of a transaction, the code, for areas of commonality, a different approach would be to look at it from the outside, the user interface. As the same effect can be achieved by any number of variations in the code, looking at the code may result in the situation where you cannot see the wood for the trees, you cannot see "the big picture". If you look carefully at a transaction, any transaction, you should be able to describe it in terms of the following:

Structure - what it looks like, how many elements it contains, how they are positioned and how they are related.

Behaviour - what it does, what actions it performs, either automatically or by user selection.

Content - what data is acted upon within each element.

A particular pattern can be described in terms of its structure and behaviour, and it can be turned into a working transaction by adding in the missing ingredient, which is content. Using the subroutine analogy, the pattern (structure and behaviour) can be regarded as a subroutine and the content (list of data names and their values) can be regarded as its parameters. The reason for separating structure from behaviour it is to make it possible for different patterns to share the same structure but to have different behaviour. It then becomes possible to define transactions in terms of the transaction patterns which they use, such as:

Transaction #1 uses pattern L1 with table 'A'.

Transaction #2 uses pattern L1 with table 'B'.

Transaction #3 uses pattern L2 with tables 'A' and 'B'.

Some people may be able to see the advantage of being able to describe transactions in this way, but they may not be able to see that any further benefits can be gained, which is where they would be quite wrong. Taking the previous example where transaction #1 is similar to transaction #2, what are the programmer's options for actually building transaction #2? Typically only two options are available:

Take a copy of transaction #1, and change all the references for table 'A' to table 'B'.

Does that sound familiar? Option (2) is quicker than option (1) but it still involves a great deal of effort and allows errors to creep in. But supposing there is a third option, one that cuts out all that effort and reduces the possibility of errors? Those of you with more than two brain cells to rub together may be able to see that transaction patterns not only provide a different means for describing transactions, but they can also provide a means of implementing transactions as easily as saying:

This means that the code which implements the pattern does not have to be generated by hand, instead an existing block of pre-written code is referenced, merged with the relevant data, and a working transaction is instantly available. But how can it be possible for patterns to be implemented in such a manner? This depends entirely on the language which is being used:

For a compiled language it may be necessary to have a process which takes a pattern, takes one or more table names, then generates the source code which can then be compiled into a working transaction.

For an interpreted language where no pre-compilation is necessary it may be possible to refer to the pre-written code without having to generate a copy.

Do you see the benefit of having such a mechanism? This functionality now exists within the RADICORE framework, and allows the developer to create working transactions in just three simple steps:

This means that starting with nothing more than a database schema it is possible for the RADICORE framework to generate and run all the components for maintaining the tables within that schema without having to write a single line of code. It is possible to customise the generated code afterwards, but at least all the ground work has been done for you.

A properly crafted set of transaction patterns, with an implementation mechanism, can save time in a large number of different areas:

Time is saved when designing the application as all the possible patterns have already been mapped out. It is therefore possible to mould the design to fit these patterns without having to reinvent the wheel.

Time is saved when writing program specifications as there is no need to go into detail on the expected structure and behaviour. This is covered simply by identifying the pattern which is to be used, and the content on which it is to be used.

Time is saved when creating the model component as each database table class is generated automatically from the details which are imported into the data dictionary directly from the database schema. These class files are initially very small as the vast majority of code is inherited from an abstract table class.

Time is saved when writing transactions as there is no need to duplicate the code which deals with the structure and behaviour. This is all provided as part of the pattern. All that has to be done is to identify the content (the database table), then add in any specialist business rules into the model component.

Time is saved when performing unit testing as the common code within the pattern has already been tested. If a pattern is used 50 times then exhaustive tests need only be performed on one implementation of that pattern, not all 50.

Time is saved when writing program documentation as references to the standard pattern will cover the structure and behaviour. The only extra information required is that of the content (the application data and associated business rules).

Time is saved when performing global updates as a change can be made to a single pattern. This change is then automatically inherited by all transactions which are based on that pattern.

Time is saved by not having to correct inconsistencies which are introduced by different programmers. Transactions written from patterns will all look and behave in a consistent manner, and this removes a source of annoyance from the users.

Time is saved when discussing pattern usage among programmers as there are fewer arguments about which name is correct or which implementation is correct, so they provide a more common vocabulary.

If you want to obtain the benefits that transaction patterns can provide then the first step you must take is to recognise that they exist. This will be a physical impossibility to those who insist that design patterns are the center of their universe and to even think that something else exists, let alone could be better, is pure heresy.

Question: What is the difference between theory and practice?
Answer: In theory there is no difference, but in practice there is.

Regardless of how patterns were expected to be used by their designers, it is impossible to guarantee that they will be used only as intended. There are plenty of people out their who have more imagination than intelligence, and even though they may think that they have done a good job in theory by implementing a particular pattern in a particular way for a particular set of circumstances, in practice the results may be less than optimal (which is a polite way of saying "a pile of poo").

The Abject Poverty Pattern is evident in software that is so difficult to test and maintain that doing so results in massive budget overruns.

1.2 Blinder

The Blinder Pattern is an expedient solution to a problem without regard for future changes in requirements. It is unclear as to whether the Blinder is named for the blinders worn by the software designer during the coding phase, or the desire to gouge his eyes out during the maintenance phase.

1.3 Fallacy Method

The Fallacy method is evident in handling corner cases. The logic looks correct, but if anyone actually bothers to test it, or if a corner case occurs, the Fallacy of the logic will become known.

1.4 ProtoTry

The ProtoTry Pattern is a quick and dirty attempt to develop a working model of software. The original intent is to rewrite the ProtoTry, using lessons learned, but schedules never permit. The ProtoTry is also known as legacy code.

1.5 Simpleton

The Simpleton Pattern is an extremely complex pattern used for the most trivial of tasks. The Simpleton is an accurate indicator of the skill level of its creator.

Destructural Patterns

2.1 Adopter

The Adopter Pattern provides a home for orphaned functions. The result is a large family of functions that don't look anything alike, whose only relation to one another is through the Adopter.

2.2 Brig

The Brig Pattern is a container class for bad software. Also known as module.

2.3 Compromise

The Compromise Pattern is used to balance the forces of schedule vs. quality. The result is software of inferior quality that is still late.

2.4 Detonator

The Detonator is extremely common, but often undetected. A common example is the calculations based on a 2 digit year field. This bomb is out there, and waiting to explode!

2.5 Fromage

The Fromage Pattern is often full of holes. Fromage consists of cheesy little software tricks that make portability impossible. The older this pattern gets, the riper it smells.

2.6 Flypaper

The Flypaper Pattern is written by one designer and maintained by another. The designer maintaining the Flypaper Pattern finds herself stuck, and will likely perish before getting loose.

2.7 ePoxy

The ePoxy Pattern is evident in tightly coupled software modules. As coupling between modules increases, there appears to be an epoxy bond between them.

Misbehavioral Patterns

3.1 Chain of Possibilities

The Chain of Possibilities Pattern is evident in big, poorly
documented modules. Nobody is sure of the full extent of its
functionality, but the possibilities seem endless. Also known as
Non-Deterministic.

3.2 Commando

The Commando Pattern is used to get in and out quick, and get the job
done. This pattern can break any encapsulation to accomplish its
mission. It takes no prisoners.

3.3 Intersperser

The Intersperser Pattern scatters pieces of functionality throughout a
system, making a function impossible to test, modify, or understand.

3.4 Instigator

The Instigator Pattern is seemingly benign, but wreaks havoc on other
parts of the software system.

The Medicator Pattern is a real time hog that makes the rest of the
system appear to be medicated with strong sedatives.

3.7 Absolver

The Absolver Pattern is evident in problem ridden code developed by
former employees. So many historical problems have been traced to this
software that current employees can absolve their software of blame by
claiming that the absolver is responsible for any problem
reported. Also known as It's-not-in-my-code.

3.8 Stake

The Stake Pattern is evident in problem ridden software written by designers who have since chosen the management ladder. Although
fraught with problems, the manager's stake in this software is too high to allow anyone to rewrite it, as it represents the pinnacle of
the manager's technical achievement.

3.9 Eulogy

The Eulogy Pattern is eventually used on all projects employing the other 22 Resign Patterns. Also known as Post Mortem.

3.10 Tempest Method

The Tempest Method is used in the last few days before software delivery. The Tempest Method is characterized by lack of comments, and introduction of several Detonator Patterns.

3.11 Visitor From Hell

The Visitor From Hell Pattern is coincident with the absence of run time bounds checking on arrays. Inevitably, at least one control loop per system will have a Visitor From Hell Pattern that will overwrite critical data.

As well as knowing what design patterns are, it is also important to know what they are NOT:

A design pattern is not a template, it is instead a description of a proposed solution with no particular implementation. In theory you can take any design pattern and write code to implement it in any language, but if a pattern is built specifically for the object-oriented paradigm, then it may be difficult to implement in a non-OO language.

A particular design pattern may have been developed to solve a particular problem with a particular programming language, but if you are using a different language which does not have the same problem then attempting to implement that pattern may actually be counter-productive.

A design pattern is NOT a framework, though depending on whom you speak to, a group of design patterns maybe considered as a design framework. It is possible to build a framework which implements a set of design patterns in a repeatable and consistent manner (see RADICORE as an example), but a set of patterns in themselves do not constitute a framework.

Design patterns should not be applied indiscriminately. Often they achieve flexibility and variability by introducing additional levels of indirection, and that can complicate a design and/or cost you some performance. A design pattern should only be applied when the flexibility it affords is actually needed.

This habit of (theoretically) solving a problem by adding on another layer of indirection or abstraction is often over-used. A quote usually attributed either to David Wheeler or Butler Lampson reads as follows:

There is no problem in computer science that cannot be solved by adding another layer of indirection, except having too many layers of indirection.

A heavy reliance on design patterns will not necessarily make you a better programmer or make your application a better application. Consider the following:

Be careful during the design process not to over-design and make absolutely everything into a class. It is possible to take the process of abstraction too far.

Don't use a pattern just because it looks or seems 'cool'. Try to understand the pros and cons of using a particular pattern. You need to verify that you have the relevant problem which a pattern is supposed to solve, and that you accept the consequences which arise from implementing that pattern.

Just because a particular pattern is popular does not mean that you have to find some way to use it.

Try to avoid reusing the same pattern over and over again just because it is the one you know.

Do not try to build as many design patterns as possible into a single component. You may think it "clever", but to an experienced and competent programmer it demonstrates precisely the opposite.

Patterns which were designed for a statefull GUI environment may not fit comfortably in a stateless web environment.

A pattern is usually designed to solve a particular problem, or a group of related problems. If you do not have that problem then what makes you think that you need that solution?

Just because a particular pattern was designed to solve a particular problem does not mean that it is the only solution to that problem. It may be possible to achieve better results by designing a different solution or using a different pattern.

If sample source code for a particular pattern is not available in your particular language then do NOT simply convert that source code from its current language as the result could be worse than not using the pattern at all. Different languages work differently, so what is easy in one language may be difficult in another. Some languages contain problems that require patterns to provide a solution, while other languages don't have the same problems therefore do not need the same solutions.

Do not start immediately throwing patterns into a design, but use them as you go and understand more of the problem. Because of this I really like to use patterns after the fact, refactoring to patterns.

One comment I saw in a news group just after patterns started to become more popular was someone claiming that in a particular program they tried to use all 23 GoF patterns. They said they had failed, because they were only able to use 20. They hoped the client would call them again to come back again so maybe they could squeeze in the other 3.

Trying to use all the patterns is a bad thing, because you will end up with synthetic designs - speculative designs that have flexibility that no one needs. These days software is too complex. We can't afford to speculate what else it should do. We need to really focus on what it needs. That's why I like refactoring to patterns. People should learn that when they have a particular kind of problem or code smell, as people call it these days, they can go to their patterns toolbox to find a solution.

My problem with patterns is that there seems to be a central lie at the core of the concept: The idea that if you can somehow categorize the code experts write, then anyone can write expert code by just recognizing and mechanically applying the categories. That sounds great to managers, as expert software designers are relatively rare. The problem is that it isn't true.

The truth is that you can't write expert-quality code with "design patterns" any more than you can design your own professional fashion designer-quality clothing using only sewing patterns.

Just because you implement a pattern written by an expert does not automatically mean that your implementation is exactly the same quality as that which the expert would write. The implementation is yours, not that of the expert, so the quality of the implementation is down to your skills and not those of the expert.

You should also be aware that there is no single collection of patterns that means all things to all men. Many books have been written by different authors, and for a particular problem each book may contain a variety of alternative patterns. Some developers have a tendency to get locked in to a particular set of patterns from a particular author, and they judge other people's work by comparing it with their implementation of these particular patterns. A common criticism of my work by so-called 'experts' is that it fails to implement pattern 'so-and-so' correctly. For a prime example take this comment from lastcraft:

There is nothing innovative in your system except where you have committed some kind of random design error. The table data gateway and row data gateway patterns are the most primitive of all, but somehow you still managed to mix them into a confusing mess. You have used a TransformView over a TemplateView in the one and only set up where it's complete overkill. TransformView is way more infrastructure than templating and poses restrictions on the skills of the developers and designers.

My response to comments such as these is quite simple:

My design is not supposed to be an implementation of those particular patterns at all. I have not read the book by your favourite author, so none of my designs are based on his patterns. Any comparisons are therefore flawed.

There is no such thing as a 'wrong' implementation of a design pattern. Provided that the objectives of the pattern are met then any implementation (provided that it works) is acceptable.

I believe that it is a good idea for every developer to be aware of design patterns, but it is also important to know how and when to use them. If you implement the right patterns in an intelligent fashion then the results can be well worth the effort, but the converse is also true. The wrong pattern, or a badly implemented pattern, may yield little or even negative benefit. A design pattern is not the *ONLY* solution to a given problem, and in some cases it may not even be the *BEST* solution. Instead of solving some hypothetical problems, the use of design patterns may simply move the problem from one piece of code to another, or may even introduce a new set of problems. I have seen cases where a working solution, which was not based on any particular patterns, was turned into a slow-running and difficult-to-maintain mess simply because some idiot-who-should-have-known-better insisted that without the use of design patterns, and lots of them, the solution was not "proper", it was not "pure", it was not "fashionable".

Anything which can be used can also be over-used, mis-used or even ab-used, and design patterns are no exception. Some programmers use a design pattern just because it is there instead of when they have a problem which is addressed by that pattern. I have even heard of programmers whose ambition it is to write a program containing every single design pattern that they know of. Where some patterns are supposed to be appropriate for only a particular set of circumstances, there are some programmers who insist on using those patterns in all possible circumstances. Take the factory pattern for example. This is only supposed to be used when you want to instantiate an object from one of several classes, so why do some programmers insist on using a factory for every object even when there is only one possible class? Why do some programmers never stop with a single factory and think it would be 'cool' to have multiple layers of factory)?

Those programmers who brag about the number of design patterns they use are barking up the wrong tree as far as I am concerned - I am decidedly unimpressed, underwhelmed, uninspired and uninterested. It is not the number of patterns you implement but how you implement them that makes an impact. I consider design patterns to be nothing more than a guide for beginners, much like training wheels on a bicycle or a painting-by-numbers kit for a budding artist. They are there to teach the basics, but once learned they should be discarded otherwise they become a limitation instead of an inspiration.

In my humble opinion those code monkeys who think that design patterns are the best thing since sliced bread are not as clever as they think and are simply using design patterns as a crutch to hide their lack of knowledge and ability.