Decorator Design Pattern

Merhaba, design patternleri yazmaya devam ediyorum. Bir önceki yazıda chain of responsibility pattern den bahsetmiştim. Bu yazıda ise structural design pattern olan decorator patterni üzerinde duracağım

Nedir?

Decorator pattern adı üstünde bir nesneyi dekore etmek için kullanılır. Dekore etmekten kastım yeni özellik eklemek gibi düşünülebilir. Aslında yeni davranış eklemek desek daha doğru olur.

Örneğin sizin bir nesneniz var ama bir zaman sonra bu nesneye yeni davranışlar eklemek istiyorsunuz ve bunu daha önce yazılmış hiçbir classa dokunmadan yapmak istiyorsunuz. Yani yeni class ekleyerek daha önceki classları davranış bakımından genişletiyorsunuz.

Ne zaman kullanılır?

  • Runtime da daha nesneyi kullanan kodlara dokumadan o nesneye yeni bir davranış ataması yapmak gerektiğinde
  • Interface ile bir nesneye davranış ataması yapmak mümkün olmadığında veya çok zor olduğunda.
package blog;

public abstract class IceCreamDecorator extends IceCream{
	
	public IceCream decorator;

	public IceCreamDecorator(String type,IceCream decorator) {
		super(type);
		this.decorator=decorator;
	}

	@Override
	public String toString() {
		
		return  getType()+this.decorator.getType();
	}

	@Override
	public double cost() {
		return 0;
	}
}
package blog;

abstract public class IceCream {
	private  String type;
	
	public IceCream(String type) {
		this.type = type;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}
	
	public String toString() {
		return "Icecream:"+getType() +"cost: "+cost();
	}
	public abstract double cost();
	
}
package blog;

public class Traditional extends IceCream{

	public Traditional() {
		super("Traditional ");
		// TODO Auto-generated constructor stub
	}

	@Override
	public double cost() {
		return 2;
	}

}
package blog;

public class GrocerStore extends IceCream{

	public GrocerStore() {
		super("Grocer Store ");
	}

	@Override
	public double cost() {
		return 1;
	}

}
package blog;

public class Chocolate extends IceCreamDecorator{

	public Chocolate(IceCream decorator) {
		super("Chocolate ", decorator);
		// TODO Auto-generated constructor stub
	}

	@Override
	public double cost() {
		// TODO Auto-generated method stub
		return 1.2 + super.decorator.cost();
	}

}
package blog;

public class Lemon extends IceCreamDecorator {

	public Lemon(IceCream decorator) {
		super("lemon ", decorator);
		// TODO Auto-generated constructor stub
	}

	@Override
	public double cost() {
		// TODO Auto-generated method stub
		return 0.7 + super.decorator.cost();
	}

}
package blog;

public class Vanilla extends IceCreamDecorator{

	public Vanilla(IceCream decorator) {
		super("vanilla ", decorator);
		// TODO Auto-generated constructor stub
	}

	@Override
	public double cost() {
		// TODO Auto-generated method stub
		return 0.3 + super.decorator.cost();
	}

}
package blog;

public class Test {

	public static void main(String[] args) {

			IceCream traditional = new Traditional();
			System.out.println(traditional);
			
			IceCream grocer = new GrocerStore();
			System.out.println(grocer);
			
			IceCream vanillaWithChocolate=new Vanilla(new Chocolate(new Traditional()));
			System.out.println(vanillaWithChocolate);
			System.out.println(vanillaWithChocolate.cost());		
	}
}

Kaynak

https://sourcemaking.com/design_patterns/decorator

https://refactoring.guru/design-patterns/decorator