DESIGN PATTERNS SAGA #17: REAL WORLD SITUATIONS WITH DECORATOR

There are some situations in which we need high flexibility. Let’s consider that we want to create a flexible code for mixing a lot of different pizzas. We would not want to write all the possibilities without a pattern, right? For this reason, we want to use the Decorator pattern to gain flexibility, high cohesion, and low coupling.

pizza_decorator.PNG

Get the Design_Patterns_Saga_GitHub_Source_Code

1 – Generic interface (Component): It’s the interface with the method that will create all of the objects’ decorations.

public interface Pizza {
	public String make();
}

2 – Decorator: This is the class that makes things happen. It is on the top of all decorator classes and is responsible for decorating the objects.

public abstract class PizzaDecorator implements Pizza {

	protected Pizza customPizza;

	public PizzaDecorator(Pizza customPizza) {
		this.customPizza = customPizza;
	}

	public String make() {
		return customPizza.make();
	}

}

3 – Decorator classes: These are the classes that will decorate the final pizza. Basically, we will decorate the pizza with the toppings we want in a flexible way.

public class TuscanyDecorator extends PizzaDecorator {

	public DressingDecorator(Pizza customPizza) {
		super(customPizza);
	}

	public String make() {
		return customPizza.make() + addTuscany();
	}

	private String addTuscany() {
		return " + Tuscany";
	}

}

public class MozzarellaDecorator extends PizzaDecorator {

	public MozzarellaDecorator(Pizza customPizza) {
		super(customPizza);
	}

	public String make() {
		return customPizza.make() + addMozzarella();
	}

	private String addMozzarella() {
		return " + Mozzarella";
	}
}

4 – Concrete component: This is the base of the pizza (the dough), the component that will generate different kinds of pizzas.

public class SimplePizza implements Pizza {

	@Override
	public String make() {
		return "Base";
	}
}

5 – Unit Tests: It’s test time! Now we will top the pizza in the way we want. We will instantiate the toppings first and then we use the base of the pizza – always passing the object in the constructor of each decorator class. In the end, we invoke the generic make method and the pizza is done!

Also, there is the Java API example with File creation.

public class DecoratorTest {

	@Test
	public void decoratorTest() {
		Pizza pizza = new TuscanyDecorator(
				new MozzarellaDecorator(new SimplePizza()));

		Assert.assertEquals("Base + Mozzarella + Tuscany"
                    , pizza.make());
	}

	@Test
	public void decoratorJavaAPITest() throws IOException {
		File file = new File("./output.txt");
		file.createNewFile();

		OutputStream stream = new FileOutputStream(file);

		DataOutputStream dataStream = new DataOutputStream(stream);
		dataStream.writeChars("text");
		dataStream.close();
		stream.close();

		file.delete();
	}

}

Summary of actions:

  1. Created the generic interface of the Component with the make method.
  2. Created the Component class implementing the generic interface.
  3. Created the Decorator abstract class controlling the decoration.
  4. Created the Decorator concrete classes extending the Decorator.
  5. Decorated the Component joining the classes in the constructor.

To practice the Decorator pattern you can create another Component class, for example, a Sandwich and decorate your Sandwich as you wish. Be sure to use TDD (Test Driven Development).

DESIGN PATTERNS SAGA #17: REAL WORLD SITUATIONS WITH DECORATOR

One thought on “DESIGN PATTERNS SAGA #17: REAL WORLD SITUATIONS WITH DECORATOR

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