1,什么是装饰者模式?
!如图,在装饰模式中的各个角色有:
(1)抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
(2)具体构件(Concrete Component)角色:定义一个将要接收附加责任的类。
(3)装饰(Decorator)角色:持有一个构件(Component)对象的实例,并实现一个与抽象构件接口一致的接口。
(4)具体装饰(Concrete Decorator)角色:负责给构件对象添加上附加的责任。
2,现实生活中的例子?
我们去KFC买汉堡,汉堡有很多种,比如鸡肉汉堡,牛肉汉堡等等。还有很多配菜,比如生菜,鸡蛋,酱汁等等。我们点餐的时候通常会有如下对话:
美女店员:先生,请问您需要那种汉堡?(抽象构件)
我:鸡肉汉堡。
美女店员:先生,请问你需要加配菜吗?(具体构件)
我:需要。
美女店员:先生,请问您是要加生菜,鸡蛋还是酱汁?(装饰物)
我:加生菜吧。(具体装饰)
我:再加一个鸡蛋吧。(具体装饰)
我:多放点酱汁。(具体装饰)
看到这里,其实我们明白了,装饰者模式只有两种抽象类,一种是被装饰类,一种是装饰类。上面的例子中,汉堡是被装饰抽象类,而配菜是装饰抽象类。只不过,汉堡和配菜都可以生成具体的对象。这里我们用一张图片来说明这个例子中的关系。
3,代码实现这个故事。
3-1,先看被装饰者抽象类(Hamburger)和装饰者抽象类(Garnish),这里配菜是装饰汉堡的一部分,所以Garnish extends Hamburger,Hamburger.java可以是抽象类也可以是接口,这里我感觉用抽象类比较合适。
public abstract class Hamburger {
abstract void sale(); //销售价格
}
/**
* 配菜
* @author liu
*
*/
public abstract class Garnish extends Hamburger{
private Hamburger hamburger;
public Garnish(Hamburger hamburger){
this.setHamburger(hamburger);
}
protected abstract void addGarnish();
public Hamburger getHamburger() {
return hamburger;
}
public void setHamburger(Hamburger hamburger) {
this.hamburger = hamburger;
}
}
3-2,被装饰者具体对象,两种汉堡,继承自Hamburger,这里就不多说了。
public class BeefHam extends Hamburger{
@Override
public void sale() {
System.out.println("牛肉汉堡需要10元");
}
}
public class ChickenHam extends Hamburger{
@Override
public void sale() {
System.out.println("鸡肉汉堡需要8元");
}
}
3-3,装饰者具体对象,3种配菜。
/**
* 鸡蛋
* @author liu
*
*/
public class GarnishEgg extends Garnish{
public GarnishEgg(Hamburger hamburger) {
super(hamburger);
}
@Override
public void sale() {
System.out.println("鸡蛋需要2元");
}
@Override
protected void addGarnish() {
System.out.println("+鸡蛋");
}
}
/**
* 生菜
* @author liu
*
*/
public class GarnishLettuce extends Garnish{
public GarnishLettuce(Hamburger hamburger) {
super(hamburger);
}
@Override
public void sale() {
System.out.println("生菜需要1元");
}
@Override
protected void addGarnish() {
System.out.println("+生菜");
}
}
/**
* 酱汁
* @author liu
*
*/
public class GarnishSauce extends Garnish{
public GarnishSauce(Hamburger hamburger) {
super(hamburger);
// TODO Auto-generated constructor stub
}
@Override
public void sale() {
System.out.println("酱汁需要0元");
}
@Override
protected void addGarnish() {
System.out.println("+酱汁");
}
}
3-4,测试类
public class Test {
public static void main(String[] args){
System.out.println("客人A开始点菜");
Hamburger hamA = new ChickenHam();
hamA.sale();
GarnishEgg eggA = new GarnishEgg(hamA);
eggA.addGarnish();
eggA.sale();
GarnishLettuce lettuceA = new GarnishLettuce(hamA);
lettuceA.addGarnish();
lettuceA.sale();
System.out.println("客人B开始点菜");
Hamburger hamB = new BeefHam();
hamB.sale();
Garnish Garnish_B1 = new GarnishSauce(hamB);
Garnish_B1.addGarnish();
Garnish_B1.sale();
Garnish Garnish_B2 = new GarnishLettuce(hamB);
Garnish_B2.addGarnish();
Garnish_B2.sale();
}
}
3-5,测试结果
客人A开始点菜
鸡肉汉堡需要8元
+鸡蛋
鸡蛋需要2元
+生菜
生菜需要1元
客人B开始点菜
牛肉汉堡需要10元
+酱汁
酱汁需要0元
+生菜
生菜需要1元
3-6,代码下载
http://download.csdn.net/detail/js_liuyangchao/9556666