The Abuse of Design Patterns in writing a Hello World Program

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?

  1. The code is too complex for a hello world program.
  2. It contains the flexibility that we will never need.
  3. The time spent in designing and implementing is a total waste.
  4. There is a class explosion.
  5. It violates the KISS principle. [3]
  6. 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.

About these ads
This entry was posted in Design Pattern and tagged . Bookmark the permalink.

11 Responses to The Abuse of Design Patterns in writing a Hello World Program

  1. Seems you are getting hard time to KISS ;)

    Anyway.. brilliant post.. though a bit tough but read till end!

  2. Mithu says:

    খাইছে!

  3. Daniel says:

    Great article. I was googling abuse of design patterns and found this article. I inherited some tangled code to maintain (co-worker quit), and everyone I work with deals with an older, non-object-oriented system. It was hard to explain to them why my job is much more difficult. I think I will just forward them this link. Thanks!

  4. Pingback: 겸손한 개발자 | eastdg

  5. Pingback: KISS (Keep it simple, stupid) y Patrones de Diseño | Pensando bajo la lluvia

  6. adi says:

    wow i start with this one but 3 days i never get complied :(
    just want to remember this post, i will start with the basic java. i hope can understand and get what the writer want to share

    • taskinoor says:

      Clarification: This post is not about Java, it’s about Design Patterns which is not specific to Java. Java is used here simply as an implementation language.

  7. abel says:

    por algo empiezo a lo basico en java y entender y analizar y seguir la sitanxis de cada linea del codigo.

  8. Bad design here:

    private ArrayList observers;

    class should be used, List or Collection are good candidates.

    :-)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s