Java Articles

Advertisement

Decorator Design Pattern

by Ram Satish

Share

Decorators provide a flexible alternative to add behavior without changing the class hierarchy.

Decorator Pattern Example

Imagine that there is a movie director and is making a new movie. In the movie, there is a character who is really old with a long beard and torn clothes. Also, this character lives in a dense forest and speaks the tribal’s language. As a director, it won’t be possible for him to look for people who exactly fit the bill, in this case an old man, with long white beard, torn clothes and who speaks the tribal’s language.

He will simply hire one of the best actors within the budget, then ask a make up artist to change his appearance, costume designer to come up with a costume and a dialect expert to teach him a bit of the tribal language and their accent. This is exactly what is a decorator pattern does.

Advertisement

As a director, his challenge would be to build the character. CharacterAspect represents one aspect of a character.

CharacterAspect:

package patterns;

public interface CharacterAspect {
String buildCharacter();
}

In our example, the actor represents the base aspect of the Character which of course will be built further with other Character Aspect classes.

Actor:

package patterns;

public class Actor implements CharacterAspect {
public String buildCharacter(){
return "Actor";
}
}

CharacterAspectDecorator takes the responsibility of building the character and decorating it layer by layer.

CharacterAspectDecorator:

package patterns;

public class CharacterAspectDecorator implements CharacterAspect {
private CharacterAspect characterAspect;

public CharacterAspectDecorator(CharacterAspect characterAspect) {
this.characterAspect = characterAspect;
}

public String buildCharacter(){
return characterAspect.buildCharacter();
}
}

The concrete decorator classes take care of building one specific aspect of character.

 MakeupArtist:

package patterns;

public class MakeupArtist extends CharacterAspectDecorator {
private String makeupLook;

public MakeupArtist(CharacterAspect characterAspect, String makeupLook) {
super(characterAspect);
this.makeupLook = makeupLook;
}

public String buildCharacter(){
return super.buildCharacter() + applyMakeUp();
}

private String applyMakeUp() {
return "\nmodeled as " + makeupLook;
}
}

HairStylist:

package patterns;


public class Hairstylist extends CharacterAspectDecorator {
private String hairStyle;

public Hairstylist(CharacterAspect characterAspect, String hairStyle) {
super(characterAspect);
this.hairStyle = hairStyle;
}

public String buildCharacter(){
return super.buildCharacter() + hairStyling();
}

private String hairStyling() {
return "\nwith " + hairStyle;
}
}

CostumeDesigner:

package patterns;

public class CostumeDesigner extends CharacterAspectDecorator {
private String costume;

public CostumeDesigner(CharacterAspect characterAspect, String costume) {
super(characterAspect);
this.costume = costume;
}

public String buildCharacter(){
return super.buildCharacter() + wearTheCostume();
}

private String wearTheCostume() {
return "\nin " + costume;
}
}

In the below test case, I show how the actor’s character is built.

DecoratorTests:

package patterns;

import junit.framework.TestCase;

public class DecoratorTests extends TestCase {
public void testDecorateActor() {
CharacterAspect actor = new Actor();
actor = new MakeupArtist(actor, "an old man with a long beard");
actor = new Hairstylist(actor, "grey hair");
actor = new CostumeDesigner(actor, "torn clothes");
actor = new DialectExpert(actor);
System.out.println(actor.buildCharacter());
}
}

Output:

Actor,
modeled as an old man with a long beard, 
grey hair,
in torn clothes and
speaks tribal dialect

Share

Advertisement

Related

Advertisement

Latest

Advertisement