The Decorator Pattern

Decorator Pattern

The Decorator Pattern is a pattern which allows us to attach additional responsibilities to an object dynamically. Decorators provide a flexibility alternative to subclassing for extending functionality.

The Decorator Pattern adds a new Object Oriented Principle to old ones which is:” Classes should be open for extension but closed for modification”. We both know how hard it is to make our code well written debug them without error, that is why this principle tells us that once well written it shouldn’t be modified, but could be used by other classes by extension.

In this pattern we can see that composition and delegation can be used to add new behaviors at runtime which give us more flexibility to add or remove characteristics of an object by a set of classes that are used to wrap the main object. The number of small object or classes should be limited otherwise the overuse might be complex.

Let’s illustrate this pattern by an example of a coffee beverage.

package com.decorator.pack1;

/**
 * This class is an abstract one which will be used to set and get description
 * @author Pascal
 *
 */
public abstract class Beverage {
	String description = "Unknown Beverage";
	
	/**
	 * This method return the description of this class
	 * @return: String description
	 */
	public String getDescription(){
		return description;
	}
	
	/*
	 * Set the price of the beverage
	 */
	public abstract double cost();
}
package com.decorator.pack1;

/**
 * This class has the duty to get the wrapper(or decorator) description
 * @author Pascal
 *
 */
public abstract class CondimentDecorator extends Beverage{
	
	public abstract String getDescription();

}

package com.decorator.pack1;

/**
 * Is A Beverage class by inheritance
 * @author Pascal
 *
 */
public class DarkRoast extends Beverage{
	
	public DarkRoast(){
		description = "DarkRoast";
	}

	@Override
	public double cost() {
		// TODO Auto-generated method stub
		return .99;
	}

}

package com.decorator.pack1;

/**
 * Is A Beverage class by inheritance
 * @author Pascal
 *
 */
public class Decaf extends Beverage{
	
	public Decaf(){
		description = "Decaf";
	}

	@Override
	public double cost() {
		// TODO Auto-generated method stub
		return 1.05;
	}

}

package com.decorator.pack1;

/**
 * Is A Beverage class by inheritance
 * @author Pascal
 *
 */
public class Espresso extends Beverage{
	
	public Espresso(){
		description = "Espresso";
	}

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

}

package com.decorator.pack1;

/**
 * Is A Beverage class by inheritance
 * @author Pascal
 *
 */
public class HouseBlend extends Beverage{
	
	public HouseBlend(){
		description = "HouseBlend coffee";
	}

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

}

package com.decorator.pack1;

/**
 * IS A CondimentDecorator
 * @author Pascal
 *
 */
public class Mocha extends CondimentDecorator{
	
	Beverage beverage;
	
	public Mocha(Beverage beverage){
		this.beverage = beverage;
	}

	@Override
	public String getDescription() {
		return beverage.getDescription()+",Mocha";
	}

	@Override
	public double cost() {
		return 0.20+beverage.cost();
	}

}

package com.decorator.pack1;

/**
 * IS A CondimentDecorator
 * @author Pascal
 *
 */
public class Soy extends CondimentDecorator{
	
	Beverage beverage;
	
	public Soy(Beverage beverage){
		this.beverage = beverage;
	}

	@Override
	public String getDescription() {
		// TODO Auto-generated method stub
		return beverage.getDescription()+", Soy";
	}

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

}

package com.decorator.pack1;

/**
 * IS A CondimentDecorator
 * @author Pascal
 *
 */
public class SteamedMilk extends CondimentDecorator{
	Beverage beverage;
	
	public SteamedMilk(Beverage beverage){
		this.beverage = beverage;
	}

	@Override
	public String getDescription() {
		// TODO Auto-generated method stub
		return beverage.getDescription()+", Steamed Milk";
	}

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

}

package com.decorator.pack1;

/**
 * IS A CondimentDecorator
 * @author Pascal
 *
 */
public class Whip extends CondimentDecorator{
	public Beverage beverage;
	
	public Whip(Beverage beverage){
		this.beverage = beverage;
	}

	@Override
	public String getDescription() {
		// TODO Auto-generated method stub
		return beverage.getDescription()+", whip";
	}

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

package com.decorator.pack1;

/**
 * This is the main class for this project, which means the order
 * @author Pascal
 *
 */
public class StarbuzzCoffee {

	public static void main(String[] args) {
		Beverage beverage = new Espresso();
		System.out.println(beverage.getDescription()+" $"+beverage.cost());
		
		Beverage beverage2 = new DarkRoast();
		beverage2 = new Mocha(beverage2);
		beverage2 = new Mocha(beverage2);
		beverage2 = new Whip(beverage2);
		System.out.println(beverage2.getDescription()+" $"+beverage2.cost());
		
		Beverage beverage3 = new HouseBlend();
		beverage3 = new Soy(beverage3);
		beverage3 = new Mocha(beverage3);
		beverage3 = new Whip(beverage3);
		System.out.println(beverage3.getDescription()+" $"+beverage3.cost());
		
	}

}

你可能感兴趣的:(java,Decorator,Pattern)