首页 > 代码库 > 设计模式 - 装饰者模式(Decorator Pattern) 详解

设计模式 - 装饰者模式(Decorator Pattern) 详解

装饰者模式(Decorator Pattern) 详解


本文地址: http://blog.csdn.net/caroline_wendy/article/details/26707033


装饰者模式(Decorator Pattern):动态地将责任附加到对象上. 若要扩展功能, 装饰者提供了比继承更有弹性的替代方案.


使用方法:


1. 首先创建组件(Component)父类, 所有类,具体组件(Concrete Component)装饰者(Decorator)都属于这一类型, 可以进行扩展;

可以是抽象类(abstract class), 也可以是接口(interface);

代码:

/**
 * @time 2014年5月23日
 */
package decorator;

/**
 * @author C.L.Wang
 *
 */
public abstract class Beverage {
	String description = "Unkown Beverage";
	
	public String getDescription() {
		return description;
	}
	
	public abstract double cost();
}

2. 装饰者(Decorator)类父类, 继承组件(component)父类, 但是不要实现接口函数, 由它的继承类(具体的装饰者)去实现,

可以是抽象类(abstract class), 也可以是接口(interface);

代码:

/**
 * @time 2014年5月23日
 */
package decorator;

/**
 * @author C.L.Wang
 *
 */
public abstract class CondimentDecorator extends Beverage {
	public abstract String getDescription();

}

3. 具体组件(Concrete Component), 即装饰者(Decorator)需要装饰的基础, 继承组件(Component)父类;

代码:

/**
 * @time 2014年5月23日
 */
package decorator;

/**
 * @author C.L.Wang
 *
 */
public class DarkRoast extends Beverage {

	public DarkRoast() {
		description = "Dark Roast";
	}
	
	/* (non-Javadoc)
	 * @see decorator.Beverage#cost()
	 */
	@Override
	public double cost() {
		// TODO Auto-generated method stub
		return 0.99;
	}

}


/**
 * @time 2014年5月23日
 */
package decorator;

/**
 * @author C.L.Wang
 *
 */
public class Decat extends Beverage {

	public Decat() {
		description = "Decat";
	}
	
	/* (non-Javadoc)
	 * @see decorator.Beverage#cost()
	 */
	@Override
	public double cost() {
		// TODO Auto-generated method stub
		return 1.05;
	}

}


/**
 * @time 2014年5月23日
 */
package decorator;

/**
 * @author C.L.Wang
 *
 */
public class Espresso extends Beverage {

	public Espresso() {
		description = "Espresso";
	}
	
	/* (non-Javadoc)
	 * @see decorator.Beverage#cost()
	 */
	@Override
	public double cost() {
		// TODO Auto-generated method stub
		return 1.99;
	}

}


/**
 * @time 2014年5月23日
 */
package decorator;

/**
 * @author C.L.Wang
 *
 */
public class HouseBlend extends Beverage {

	public HouseBlend() {
		description = "House Blend Coffee";
	}
	
	/* (non-Javadoc)
	 * @see decorator.Beverage#cost()
	 */
	@Override
	public double cost() {
		// TODO Auto-generated method stub
		return .89;
	}

}

4. 装饰者(Decorator)类继承装饰者父类, 实现组件父类的接口装饰者父类的接口.

代码:

/**
 * @time 2014年5月23日
 */
package decorator;

/**
 * @author C.L.Wang
 *
 */
public class Milk extends CondimentDecorator {

	Beverage beverage;
	
	public Milk(Beverage beverage) {
		this.beverage = beverage;
	}
	
	/* (non-Javadoc)
	 * @see decorator.CondimentDecorator#getDescription()
	 */
	@Override
	public String getDescription() {
		// TODO Auto-generated method stub
		return beverage.getDescription() + ", Milk";
	}

	/* (non-Javadoc)
	 * @see decorator.Beverage#cost()
	 */
	@Override
	public double cost() {
		// TODO Auto-generated method stub
		return 0.10 + beverage.cost();
	}

}


/**
 * @time 2014年5月23日
 */
package decorator;

/**
 * @author C.L.Wang
 *
 */
public class Mocha extends CondimentDecorator {

	Beverage beverage;
	
	public Mocha(Beverage beverage) {
		this.beverage = beverage;
	}
	
	/* (non-Javadoc)
	 * @see decorator.CondimentDecorator#getDescription()
	 */
	@Override
	public String getDescription() {
		// TODO Auto-generated method stub
		return beverage.getDescription() + ", Mocha";
	}

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

}


/**
 * @time 2014年5月23日
 */
package decorator;

/**
 * @author C.L.Wang
 *
 */
public class Soy extends CondimentDecorator {

	Beverage beverage;
	
	public Soy(Beverage beverage) {
		this.beverage = beverage;
	} 
	
	/* (non-Javadoc)
	 * @see decorator.CondimentDecorator#getDescription()
	 */
	@Override
	public String getDescription() {
		// TODO Auto-generated method stub
		return beverage.getDescription() + ", Soy";
	}

	/* (non-Javadoc)
	 * @see decorator.Beverage#cost()
	 */
	@Override
	public double cost() {
		// TODO Auto-generated method stub
		return 0.15 + beverage.cost();
	}

}


/**
 * @time 2014年5月23日
 */
package decorator;

/**
 * @author C.L.Wang
 *
 */
public class Whip extends CondimentDecorator {

	Beverage beverage;
	
	public Whip(Beverage beverage) {
		this.beverage = beverage;
	}
	
	/* (non-Javadoc)
	 * @see decorator.CondimentDecorator#getDescription()
	 */
	@Override
	public String getDescription() {
		// TODO Auto-generated method stub
		return beverage.getDescription() + ", Whip";
	}

	/* (non-Javadoc)
	 * @see decorator.Beverage#cost()
	 */
	@Override
	public double cost() {
		// TODO Auto-generated method stub
		return 0.10 + beverage.cost();
	}

}

5. 测试, 创建具体组件(Concrete Component), 再一层一层添加装饰者(Decorator)类, 可以实现动态的组合;

代码:

/**
 * @time 2014年5月23日
 */
package decorator;

/**
 * @author C.L.Wang
 *
 */
public class StarbuzzCoffee {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		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());
	}
	

}

6. 输出:

Espresso $1.99
Dark Roast, Mocha, Mocha, Whip $1.49
House Blend Coffee, Soy, Mocha, Whip $1.34

面向对象的原则:

对扩展开发, 对修改关闭.