设计模式---装饰者模式

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值