ghytred.com


NewsLook for Outlook

Patterns and OO
WhatArePatterns
The Web Site you seek
Cannot be located, so
Waste your time here

Contents

History

The origin of design patterns lies in work done by an architect named Christopher Alexander during the late 1970s. He began by writing two books, A Pattern Language and A Timeless Way of Building which, in addition to giving examples, described his rationale for documenting patterns.
The software pattern movement started slowly, and did not really impinge on the majority of software developers until in 1995 Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides published Design Patterns: Elements of Reusable Object-Oriented Software, which has been followed by many articles in trade journals, and in many additional books.

Patterns Defined

A pattern is a proven solution to a problem in a context
Or
Each pattern is a three-part rule, which expresses a relation between a certain context, a problem, and a solution (Alexander)

Patterns are devices that allow programs to share knowledge about their design. In our daily programming, we encounter many problems that have occurred, and will occur again. The question we must ask ourselves is how we are going to solve it this time. Documenting patterns is one way that you can reuse and possibly share the information that you have learned about how it is best to solve a specific program design problem.

The general form for documenting patterns is to define items such as:
  • The motivation or context that this pattern applies to.
  • Prerequisites that should be satisfied before deciding to use a pattern.
  • A description of the program structure that the pattern will define.
  • A list of the participants needed to complete a pattern.
  • Consequences of using the pattern...both positive and negative.
  • Examples!

Example Pattern Definition (from GoF)

IntentWhat the pattern does (short)
Also known asAny other names
Motivation The problem the pattern is intended to solve (long)
ApplicabilityThe context in which the pattern can solve the problem
StructureA generalised UML Static Class diagram of the classes in the pattern
ParticipantsA short description of each of the classes used in the pattern
Collaborations A short description of interactions between participants
ConsequencesThe advantages and disadvantages of using the pattern
ImplementationWill generally contain an equivalent of the phrase "Consider the following issues when implementing this pattern:" followed by fairly detailed examples.
Sample codeAnnotated code of an example of this pattern
Known UsesExamples of places where the pattern has been used � to good or bad effect.
Related PatternsPatterns which may be used by this one, or which use this one.

What a pattern is not

Is this a pattern? This extract is the first two paragraphs of one section of an article. The remaining paragraphs do not mention anything pattern-related.

Object Identifier Pattern
In order to synchronize identity and relationships between the middle tier objects and the database rows, we will use the Object Identifier (OID) pattern. This pattern calls for each object to be assigned a unique value. These OID values must correlate to primary key values in the database. Each new object created in the system must be assigned a unique OID. This OID value can be alphanumeric, but should probably be a long integer. At a minimum, the OID must be unique over a class type and probably any subclasses. This strategy has an immediate effect on the database structure. To fully take advantage of the OID strategy, the database should use surrogate keys for identification rather than one or more fields with business meaning. Surrogate keys are typically an autonumber field in SQL Server or generated by a Sequence in Oracle. These keys are created by the database itself and have no meaning other than as an identifier.

I would say that this is not a pattern, it's a buzz-word. There is nothing wrong with anything in the article � it just doesn't use patterns save as buzz-words. Also the solution presented is too trivial to be a pattern: use AutoNumber or a Sequence. Well duh.
I have in fact seen something which could be called an 'Object Identifier Pattern', at Scott Ambler's excellent site, as part of a large, complex article - one in a series - about OO-RDBMS mapping. He doesn't actually give a representative implementation of it, but he does discuss how to assign OID's in a distributed environment. However, his description is merely part of a much longer article and although it has the capability to become a pattern, it isn't yet. I'd still use it and name the objects as though they were a formal pattern, though. (By the way, the Scott Ambler paper above is well worth a read, if only as an example of a very clear way to write about a complex problem. If you're interested in actually writing a Persistence Layer, it's pure gold.)

Types of Pattern

The GoF book splits its patterns into three types:
  • Creational
  • Structural
  • Behavioural
These are not the only possible classifications. There are for instance several patterns relating to translating between OO systems and RDMBS's. These are rather larger than most patterns (I personally am not sure that they should be called Patterns at all) and cannot be classified in this way at all. (See particularly http://www.objectarchitects.de/ObjectArchitects/orpatterns/index.htm and http://www.ksc.com/articles.htm for examples.)

Creational Patterns

These deal, obviously enough, with ways to create objects. When using polymorphism (inheritance or interface based) picking the right type to actually instantiate may not be totally straightforward. These patterns move this decision-making process away from the place the eventual object is used and so free the user of what, to it, is extraneous clutter.

Structural Patterns

These involve ways to structure the design of a system. Their effect, amongst other things, is very often to reduce coupling (dependencies) between classes that really have no need to know about each other, and increase their individual cohesion.

Behavioural Patterns

These describe ways in which classes or objects can interact and distribute responsibility sensibly.

Example pattern implementation: A Factory pattern

Factory method is a Creational pattern. It is used when there are several different sub-types of a particular class and the decision which one to use is either non-obvious or should not be made by the user of the class.
This is a very basic version of Factory Method. The problem is that this system can use one of any number of RDBMS', and each RDBMS requires a different bit of code to actually access the database. Rather than put potentially lots of decision logic about which RDBMS is being used in the main-line code of the client, abstract this logic to a Factory class which returns one of a number of compatible database manipulation classes.

Client Code:

GatewayDB db = GatewayDBFactory.DB(); string sql = "select count(*) from orders where rec-status <> 0"; DataSet ds = db.Select(sql);

GatewayDBFactory class:

public class GatewayDBFactory { private GatewayDBFactory() { } public static GatewayDB DB() { string dbType = ConfigurationSettings.ApplicationSetting["DBType"]; string cs = ConfigurationSettings.ApplicationSetting["GatewayConnectionString"]; switch (dbType) { case "SQLServer": return new GatewaySqlDB(cs); case "Progress": return new GatewayProgressDB(cs); case ""ProgressV9": return new GatewayProgressV9DB(cs); case "Oracle": return new gatewayOracleDB(cs); default: return null; } } }

Abstract GatewayDB class:

public abstract class GatewayDB { internal GatewayDB (string connectionString) { this.connectionString = connectionString; } protected string connectionString; public virtual DataSet Select(string sql); public virtual void Execute(string sql); }

Concrete DB Classes

The concrete classes - GatewayProgressDB, GatewaySqlDB, etc - inherit from GatewayDB. They have internal constructors, so can only be created by the Factory class, or another class in their namespace. Note that the same effect would have been achieved if instead of using inheritance, an Interface had been used. In that case, the two concrete classes would implement the interface rather than inherit and the Factory Method would return the concrete class constructed as IGatewayDB.

Random Notes

Patterns apply to micro-architectures, not macro. The example above is quite small; most implementations will take up more code, but each one will not be a significant part of the size of a system. Occasionally in comp.software.patterns someone posts something like "I am writing an Accounting system. Does anyone have a good pattern for this?" The only possible answer to this is "Ha ha ha!".

Apart from actually solving some problems in the design of a program, Patterns provide a vocabulary to talk about the structure of a system. If someone says something like "The appropriate database wrapper is given by a Factory" then I know to expect code very similar to the example above; if I see a class called CustomerFactory then I know to expect there to be several different types of Customer classes in the system and that choosing the correct one is not trivial; and so on. This aspect of the value of patterns - as a method os communication about the design - is sometimes not stressed enough.

The language you write in affects not only the implementation of individual patterns, but also sometimes whether a pattern is visible at all. VB6 Forms, for example, uses the Observer pattern extremely heavily but any mention of it is redundant as, well, that's how VB Forms work. Similarly, C# and Java implementations of Observer will be different as one might use Delegates and the other might use anonymous inner classes.

It is perfectly possible to write excellent software without using any Patterns at all, but you cut yourself off from distilled experience and some easy communication if you do. If you come up with some neat structure to solve a given problem, good for you! But it's not a pattern�yet. A pattern must have been used in at least two systems for it to be a real pattern � after all, it might just have been a super-cool solution applicable only to the one instance of the problem. The essence is repeatability.

References

http://hillside.net/patterns/ Lots of links, and some useful information
The Portland Pattern repository
The original Wiki site, which started off talking mostly about Patterns, but started to rapidly digress about 4 years ago.
Brad Appleton's web site. Lots of good � or at least provocative � information about software development, including this and this about patterns
Robert C Martin, at ObjectMentor, has a number of very good things, not least being this which goes through a design, applies patterns to it, and sees what comes out at the end.

Books

There are many, many, books about Patterns and I have read very few of them. My recommendations below are not exclusively about Design Patterns but are in the same sort of area which I found very useful. I would avoid books which slavishly translate the GoF book to your favourite language; the ones I've looked at miss out enough to make the Gof book necessary anyway, and once you've understood it you won't need it translated anyway. Google has enough examples available.

The GoF book goes without saying.

Martin Fowler's books include UML Distilled, the best introduction to UML which helps talk about OO designs, Analysis Patterns about - yes! - patterns in analysis, and Patterns of Enterprise Application Architecture.

Not required reading, but quite interesting. Applying UML and Patterns by Craig Larman. I think it's an excellent book. He uses "Patterns" with a slightly different meaning, and you won't really learn much about UML, but well worth a read in any case.

Return to top