1. Decorator Pattern Story java
Let’s assume you are looking for a girlfriend. There are girls from different countries such as America, China, Japan, France, etc. Different girls 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. web
Let’s change the design, and let each hobby/personality becomes a decorator which can be dynamically applied to a girl. app
2. Class Diagram ide
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. post
3. Decorator pattern Java code this
Girl.java spa
public abstract class Girl { String description = "no particular"; public String getDescription(){ return description; } } |
AmericanGirl.java code
public class AmericanGirl extends Girl { public AmericanGirl(){ description = "+American"; } } |
ChineseGirl.java orm
public class ChineseGirl extends Girl { public ChineseGirl() { description = "+Chinese"; } } |
GirlDecorator.java ip
public abstract class GirlDecorator extends Girl { public abstract String getDescription(); } |
Slim.java
public class Slim extends GirlDecorator { private Girl girl; public Slim(Girl g){ girl = g; } @Override public String getDescription() { return girl.getDescription() + "+slim"; } public void Dance(){ System.out.println("I like dancing!"); } } |
We can add more method like 「Dance()」 to each decorator without any limitations.
Cook.java
public class Cook extends GirlDecorator { private Girl girl; public Cook(Girl g) { girl = g; } @Override public String getDescription() { return girl.getDescription() + "+like cook"; } } |
Main.java
public class Main { public static void main(String args[]){ Girl g1 = new AmericanGirl(); System.out.println(g1.getDescription()); Slim g2 = new Slim(g1); System.out.println(g2.getDescription()); Cook g3 = new Cook(g2); System.out.println(g3.getDescription()); //in addition, we can add more method for decorator class g2.Dance(); } } |
Output:
+American
+American+slim
+American+slim+like cook
I like dancing!
We can also do something like this:
Girl g = new Slim(new Cook(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())