“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.” – Erich Gamma [1]

When people starts learning design patterns, they try to use patterns everywhere. They try to use patterns anyway, it does not matter whether a pattern is required or not. They think that the more patterns are used, the better is the design. The outcome is a code with unnecessary complexity. [2]

Rather that calling “using patterns”, we can call this “abusing patterns”. It is an abuse when people try to fit patterns in Hello World program.

Let’s focus on an example. The problem is the classic one: Write a program that will print Hello World on standard output.

A beginner in programming will write a code like this (well, it’s in Java):

System.out.println("hello world");

This code seems too simple. Can we use some patterns in it? Let’s see …

First we define two interfaces Subject and Observer to add Observer.

public interface Subject { public void attach(Observer observer); public void detach(Observer observer); public void notifyObservers(); } public interface Observer { public void update(Subject subject); }

Then we define two classes HelloWorldSubject and HelloWorldObserver that implements them.

public class HelloWorldSubject implements Subject { private ArrayList<Observer> observers; private String str; public HelloWorldSubject() { super(); observers = new ArrayList<Observer>(); } public void attach(Observer observer) { observers.add(observer); } public void detach(Observer observer) { observers.remove(observer); } public void notifyObservers() { Iterator<Observer> iter = observers.iterator(); while (iter.hasNext()) { Observer observer = iter.next(); observer.update(this); } } public String getStr() { return str; } public void setStr(String str) { this.str = str; notifyObservers(); } } public class HelloWorldObserver implements Observer { public void update(Subject subject) { HelloWorldSubject sub = (HelloWorldSubject)subject; System.out.println(sub.getStr()); } }

Then we add a Command.

public interface Command { void execute(); } public class HelloWorldCommand implements Command { private HelloWorldSubject subject; public HelloWorldCommand(Subject subject) { super(); this.subject = (HelloWorldSubject)subject; } public void execute() { subject.setStr("hello world"); } }

Then we add an Abstract Factory.

public interface AbstractFactory { public Subject createSubject(); public Observer createObserver(); public Command createCommand(Subject subject); } public class HelloWorldFactory implements AbstractFactory { public Subject createSubject() { return new HelloWorldSubject(); } public Observer createObserver() { return new HelloWorldObserver(); } public Command createCommand(Subject subject) { return new HelloWorldCommand(subject); } }

And finally a Singleton.

public class FactoryMakerSingleton { private static FactoryMakerSingleton instance = null; private AbstractFactory factory; private FactoryMakerSingleton() { factory = new HelloWorldFactory(); } public static synchronized FactoryMakerSingleton getInstance() { if (instance == null) { instance = new FactoryMakerSingleton(); } return instance; } public AbstractFactory getFactory() { return factory; } }

And the main class at last.

public class AbuseDesignPatterns { public static void main(String[] args) { AbstractFactory factory = FactoryMakerSingleton.getInstance().getFactory(); Subject subject = factory.createSubject(); subject.attach(factory.createObserver()); Command command = factory.createCommand(subject); command.execute(); } }

And the output is: Hello World

Wow, we have managed to use four patterns in Hello World program. (Well, there is an Iterator too, but we have used built-in Java iterator which is natural in Java). This must be a great design. So where is the problem?

The code is too complex for a hello world program. It contains the flexibility that we will never need. The time spent in designing and implementing is a total waste. There is a class explosion. It violates the KISS principle. [3] This does not serve the purpose of the problem. The purpose was to learn how to print on standard output and this code is far far away from that.

Summary: Use patterns where they are natural, do not try to use them anyway. Design Patterns is a great tool to build great software. Use them wisely, do not abuse them.

The code can be downloaded from here. Any feedback is welcome. And if anyone can manage to use more patterns in hello world then that will be great.

References:

[1] How to Use Design Patterns.

[2] Chapter 13: Patterns in the Real World from Head First Design Patterns.

[3] KISS Principle.