Java Design Pattern: Decorator – Decorate your girlfriend

Decorator pattern adds additional features to an existing object dynamically. In this post, I will use a simple example - decorate your girlfriend - to illustrate how decorator pattern works.

1. Decorator Pattern Story

Let's assume you are looking for a girlfriend. There are girls from different countries such as America, China, Japan, France, etc. They may have different personalities and hobbies. In a dating web like eharmony.com, if each type of girl is an individual Java class, there would be thousands of classes. That is a serious problem called class explosion. Moreover, this design is not extensible. Whenever there is a new girl type, a new class needs to be created.

Let's change the design, and let each hobby/personality becomes a decorator which can be dynamically applied to a girl.

2. Class Diagram

java-design-pattern-decorator
Girl is the abstract class at the top level, we have girls from different countries. With a GirlDecorator class, we can decorator each girl with any feature by adding a new decorator.

3. Decorator pattern Java code

Girl.java

public abstract class Girl {
	String description = "no particular";
 
	public String getDescription(){
		return description;
	}
}

AmericanGirl.java

public class AmericanGirl extends Girl {
	public AmericanGirl(){
		description = "+American";
	}
}

EuropeanGirl.java

public class EuropeanGirl extends Girl {
	public EuropeanGirl() {
		description = "+European";
	}
}

GirlDecorator.java

public abstract class GirlDecorator extends Girl {
	public abstract String getDescription();
}

Science.java

public class Science extends GirlDecorator {
 
	private Girl girl;
 
	public Science(Girl g) {
		girl = g;
	}
 
	@Override
	public String getDescription() {
		return girl.getDescription() + "+Like Science";
	}
 
	public void caltulateStuff() {
		System.out.println("scientific calculation!");
	}
}

We can add more method like "Dance()" to each decorator without any limitations.

Art.java

public class Art extends GirlDecorator {
 
	private Girl girl;
 
	public Art(Girl g) {
		girl = g;
	}
 
	@Override
	public String getDescription() {
		return girl.getDescription() + "+Like Art";
	}
 
	public void draw() {
		System.out.println("draw pictures!");
	}
}

Main.java

package designpatterns.decorator;
 
public class Main {
 
	public static void main(String[] args) {
		Girl g1 = new AmericanGirl();
		System.out.println(g1.getDescription());
 
		Science g2 = new Science(g1);
		System.out.println(g2.getDescription());
 
		Art g3 = new Art(g2);
		System.out.println(g3.getDescription());
	}
}

Output:


+American
+American+Like Science
+American+Like Science+Like Art

We can also do something like this:

Girl g = new Science(new Art(new AmericanGirl()));

4. Decorator Pattern Used in Java Stand Library

A typical usage of Decorator pattern is Java IO classes.

Here is a simple example - BufferedReader decorates InputStreamReader.

BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
//System.in is an InputStream object

InputStreamReader(InputStream in) - bridge from byte streams to character streams. InputSteamReader reads bytes and translates them into characters using the specified character encoding.

BufferedReader(Reader in) - read text from a character stream and buffer characters in order to provide efficient reading methods(e.g., readLine())

Category >> Design Patterns Stories  
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
<pre><code> 
String foo = "bar";
</code></pre>

  1. qi6khan . on 2013-10-29

    Should not be caltulateStuff but calculateStuff 🙂

  2. dacapo on 2013-11-2

    How to “new” ? ! ! !

  3. Kevin on 2013-11-21

    Hi,
    Sometimes you read concepts all over the net with “intuitive”,”real-life” examples. Not all examples work for everyone. This one worked for me – had a light bulb glowing above my head. Thanx for this post and keep posting.

  4. Shan on 2013-11-26

    Shouldnt the Girl.java class be actually an interface and not abstract. Anyways there are no abstract methods defined

  5. Anom on 2013-11-27

    I’m not sure if this is the best example..at the end of the main, our girl like both Science and Art, but she cannot calculateStuff, only to draw (because g3 IS-A Art).. She could calculate but not to draw if the order would have be the opposite…I’m not saying this is neccesarily “wrong”, but it doesn’t feel right either.

    I really think that the coffe example of the wikipedia (the second one in the page) is much better.

  6. koven on 2014-1-7

    I don’t understand why should the GirlDecorator extend the Girl Class, the GirlDecorator is not a Girl at all. It’s IMHO anti-pattern.
    If you just want to have the Descprition method, you should implement an interface.

  7. everrr on 2014-3-11

    agree with other guys, girl.java should be better to be replaced with an interface but an abstract class

  8. Yibin on 2014-4-6

    I don’t know why we need GirlDecorator? Can Class Science and Art extend from Girl directly?

  9. Chess_is_great on 2015-2-12

    Doing so can result in class explosion. What if the girl has 8 other features,and this 8 other features is needed on other area, and must have certain combinations. For example girl2 might have feature one and feature two, girl 3 has feature 4 and 5. Without decorator pattern, you need to create more subclasses. What if you have 100 features that has various combinations. Then you will need to create more subclassess. This will be a nightmare.

  10. Karthick M on 2015-3-10

    Yes. I think they can. If science and art extend girl directly and they compose a girl instance and a call to science [should delegate to the composed girl instance + extra functionality]
    To your argument
    For example girl2 might have feature one and feature two, girl 3 has feature 4 and 5. Without decorator pattern, you need to create more subclasses.

    Let’s say there were 100 features, you could still have 100 subclasses. And if you wanted a combination of feature 1, 2,3 then you can still live with the 100 classes(not create any new classes ) . Feature1 can compose feature 2 (as a girl) which can compose feature3(as a girl).

    This brings me to ask the question again.
    Do we really need the abstract decorator or can we live with implementing the features as subclasses which compose a girl.
    In my humble opinion, latter seems to be OK.
    Do you think that we still need the abstract decorator?

  11. karen on 2015-10-8

    This is so sexist..you could have chosen a better example.

  12. Karen on 2015-10-8
  13. Anon on 2015-11-4

    I think you could have chosen another example. This is a really good website, however, you really don’t need such an example to make your point. Maybe the predominantly male software engineers do not find this offensive ( and understandably so). As a woman who is also a software engineer, I find this objectifying women in general(unnecessary, because I understood Decorator just as well without the need to ‘decorate’ a girlfriend). Maybe some men might find my comment unnecessary, but in a field that already has such a low female population, I think we need to stop alienating women by creating such examples (which are not only unrelatable, but also offensive). I would really appreciate you changing this example.

  14. Anon on 2015-11-4

    I agree

Leave a comment

*