Design pattern decorator and java implementation
Written by Mottola Michele - Italy - Reggio Emilia   
Sunday, 23 November 2014 18:47
Last Updated on Sunday, 23 November 2014 19:03
AddThis Social Bookmark Button

what is the problem

The design pattern decorator is used in this case: i have some object and i want to add responsability.

what is the solution of decorator

To solve this problem i can use inheritance, but as we know the inheritance has some drawback and is to prefer composition over inheritance.
Alternative solution is the decorator design pattern that use composition.
Practically the decorator is a wrapper for the object whereto i want add responsability.
The advantage of this pattern is that we can add responsability at run-time, we can easily combine them and we can add responsability at some object or all.
To do that we don't have violate some bacis software design principles as SRP and OCP.

Pizza example

class diagram

In this example i want add to some object of type PizzaSimple a ham or a fungus or both.
When i do that i have to change the name of pizza and his price.
The key point of this pattern is the decorator class that contain another object of type Pizza (PizzaSimple or Decorator). Then through inheritance it modify the right methods for a right result.

Pizza.java

package decorator4;

public interface Pizza {
	public abstract void printName();
	public abstract int getPrice();

}

PizzaSimple.java

package decorator4;

public class PizzaSimple implements Pizza {

	public void printName() {
		System.out.println("i am a simple pizza");

	}

	public int getPrice() {
		return 5;
	}

}

Decorator.java

package decorator4;

public abstract class Decorator implements Pizza {

	private Pizza pizza;
	public void printName() {
		pizza.printName();

	}

	public int getPrice() {
		return pizza.getPrice();
	}

	public Decorator(Pizza pizza) {
		super();
		this.pizza = pizza;
	}

}

Ham.java

package decorator4;

public class Ham extends Decorator {

	private String name="ham";
	
	public Ham(Pizza pizza) {
		super(pizza);
	}
	private String addFuction(){
		return this.name;
	}
	
	@Override
	public void printName() {
		super.printName();
		System.out.println("with "+this.addFuction());
	}

	@Override
	public int getPrice() {
		return super.getPrice()+3;
	}

}

Fungus.java

package decorator4;

public class Fungus extends Decorator {

	public Fungus(Pizza pizza) {
		super(pizza);
	}

	@Override
	public void printName() {
		super.printName();
		System.out.println("with fungus");
	}

	@Override
	public int getPrice() {
		return super.getPrice()+2;
	}
	

}

Example.java

package decorator4;

public class Example {

	public static void main(String[] args) {
		Pizza pizza=new PizzaSimple();
		pizza.printName();
		System.out.println("the price is "+pizza.getPrice());
		
		System.out.println("-------------");
		
		Pizza pizza1=new Ham(new PizzaSimple());
		pizza1.printName();
		System.out.println("the price is "+pizza1.getPrice());
		
		System.out.println("-------------");
		
		Pizza pizza2=new Fungus(new Ham(new PizzaSimple()));
		pizza2.printName();
		System.out.println("the price is "+pizza2.getPrice());
		
		
	}

}

output

i am a simple pizza
the price is 5
-------------
i am a simple pizza
with ham
the price is 8
-------------
i am a simple pizza
with ham
with fungus
the price is 10

Note that in the class Ham i have use an addictional method and property, but in this case they aren't necessary. So i don't have add it in Fungus class.
As you can see we can create a object of type Pizza with basic price and a object of type Pizza with ham or fungus or both and give different price and name.

 

Comments  

 
#1 pizzeria a domicilio 2020-04-14 18:40
Hi there, I enjoy reading all of your post.

I like to write a little comment to support you.
 

Add comment

Security code
Refresh