crustyoldev

Opinions, observations and ramblings about Software Development

Design Patterns have flopped?

I came across this article recently “Design patterns have (mostly) flopped” from a recruitment website (if my boss is reading this, I was not looking for a new job).  The crux of their argument is “Design patterns have flopped because most programmers don’t know design patterns well enough to recognise the recurring problems that they solve.” They go on to say that the vast majority of the thousands of programmers they have asked to name some of the common patterns don’t even know what design patterns are.

I’m calling BS on their argument. Their point of view is more to do with the lack of experience the programmers have as opposed to the purpose and usefulness of design patterns.

I remember reading about design patterns for the first time in the late ’90s. It was a book called The Design Patterns Java Companion by James W. Cooper, and it described all of the Gang of Four patterns with examples in Java. At the time this book had a massive impact on the way I looked at problems and the way that I looked at code. I remember looking at the source code for Java’s Input/OutputStream hierarchy and thinking ‘What a great example of the decorator pattern’. I could add more capabilities to a stream just by wrapping it in another stream.

One thing the article does get right is describing design patterns as a way for developers to discuss complex solutions. When I am pair-programming I always find myself discussing implementation details using desing patterns as it is much easier to tell someone “Lets use the Observer pattern here to decouple changes in the data from the classes that need to act on it” than it is to describe the implementation step by step.  No matter which domain you work in (e.g. finance, health, telecommunications etc.) the same fundamental concepts usually apply. You may have a class that needs to perform a calculation differently depending on the context it is being used in (Strategy pattern). Or you might be trying to develop a simple interface for a complex sub-system (Facade pattern).

If design patterns have supposedly flopped then why are they at the core of all of the software we depend on today? Spring MVCs DispatcherServlet is based on the Front Controller pattern (in fact MVC is a pattern too!). Most of the game AI used today is implemented using patterns such as State (to control the behaviour of NPCs) and Composite (to perform command queueing) to only name a few.

Design patterns have not flopped. Developers who cannot work out where a design pattern might help them solve a problem need to do a lot more reading and study a lot more code. Design patterns are one of the most important tools in a developers toolbox and a skilled craftsman should never blame his tools or in this case, not have the right tools for the job.

I give the orders around here!

I have been programming since I got my first Commodore 64 as a nine year old kid.  However I still think I have so much to learn when it comes to writing good code.

In my quest to improve I have learnt many different languages. Most of them are predominantly object oriented (OO).

What suprises me though in most of the books, magazines and on-line articles that I have read is the amount of horrible OO code used in examples.

The most violated principle I see is the “Tell, Don’t Ask” principle. This principle states that an object should tell other objects what to do and not query other objects for state to make decisions (querying objects for state to make decisions is also referred to as ‘Feature Envy’).  In Object Oriented Programming an object is defined as having state and operations that manipulate that state.

In his book ‘Holub on Patterns: Learning Design Patterns By Looking At Code’, Allen Holub includes a section in chapter one titled ‘Why getter and setter methods are evil’. He also contributed it as an article to JavaWorld.  It should be a “must read” for any OO developer.

I have worked with developers whose first step after declaring attributes on a class is to add getters and setters. The JavaBean specification has a lot to answer for in promoting this culture. It was deemed a good way to write re-usable modular components but the world has come a long way since then.

Writing classes with getters and setters leads to procedural code. Logic that operates on data retrieved from getters ends up spread out across an application and is often duplicated across an application (violating another principle DRY – Don’t Repeat Yourself).  This leads to unmaintainable code as any change to a class causes a ripple effect throughout the application.

By exposing the data you also prevent easy refactoring of the class because any change to the way an attribute is represented affects any other object that has access to that attribute.

Another side-effect of violating the Tell, Don’t Ask principle is that your tests end up being very state-based with stubs requiring a lot of expectations. This can make it very hard to understand what is actually being tested.

A third principle you will probably end up violating is the Principle of Least Knowledge (or LoD – Law Of Demeter). This law can be summarised as follows:

A class should only talk to its immediate friends and don’t talk to strangers.

By adding getters to your class you end up writing code like:

if (person.getAddress().getCountry() == "Australia") {

This violates the Law of Demeter because the caller is too intimate with Person.  It knows that they contain an Address and that Address contains a country.  It could be written like this instead

if (person.livesIn("Australia")) {

This does not violate the Law of Demeter as the caller is only talking to their immediate friend Person and they have no knowledge of the internals.  From a Tell Don’t Ask perspective this is better because the logic for determining if the person lives in Australia is hidden within Person and if we decided to change how the country value is represented in Person it would not affect any other classes that depend on that value.

The other side effect of writing the code this way is that it displays the intent much clearer. That will be another topic that I will be touching on soon.

Some things to keep in mind to avoid violating the Tell Don’t Ask principle.

  • Think before hitting the hot keys in your IDE exercise the ‘5 Whys’ and ask yourself why you need to add a getter or setter in the first place.
  • Do not ask objects about their state, make a decision, then tell them what to do.
  • Operations belong with the class that owns the data.

Further Reading

A friend of mine is a strong advocate of this and has come up with the
East Oriented approach that explains this principle brilliantly.

Tell Don’t Ask and the effect on testing From Steve Freeman and Nat Pryce, authors of Growing Object-Oriented Software, Guided by Tests.

Post Navigation

Follow

Get every new post delivered to your Inbox.