码迷,mamicode.com
首页 > 其他好文 > 详细

装饰模式 Decorator

时间:2016-04-20 19:40:07      阅读:268      评论:0      收藏:0      [点我收藏+]

标签:

在阎宏博士的《JAVA与模式》一书中开头是这样描述装饰(Decorator)模式的:

  装饰模式又名包装(Wrapper)模式。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。

装饰模式的结构

  装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任。换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不使用创造更多子类的情况下,将对象的功能加以扩展。

  装饰模式的类图如下:

  技术分享

  在装饰模式中的角色有:

  ●  抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。

  ●  具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。

  ●  装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。

  ●  具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。

实例一

package ice;

public abstract class AbstractIceCream 
{
  public abstract int getPrice(); 
}

// 真正的冰淇淋 
class IceCream extends AbstractIceCream
{ 
  public int getPrice()
  { 
    return 2; // 原味冰淇淋只卖2块~~ 
  } 
} 
public class ChocolateAdapter extends AbstractIceCream 
{
  private AbstractIceCream iceCream;
  public ChocolateAdapter(AbstractIceCream iceCream) 
  {
    this.iceCream = iceCream;
  }

  public int getPrice() 
  {
    return this.iceCream.getPrice() + 3; // 假设加一层巧克力要加3块钱好了~
  }
}

public class BlueberryAdapter extends AbstractIceCream
{
  private AbstractIceCream iceCream; 
  public BlueberryAdapter(AbstractIceCream iceCream)
  {
    this.iceCream = iceCream ;
  } 

  public int getPrice() 
  { 
    return this.iceCream.getPrice()+4; //假设加一层巧克力要加4块钱好了~
  }
}

//顾客来了 
public class Client 
{
  public static void main(String args[]) 
  {
    // 给我来个蓝莓冰淇淋
    AbstractIceCream blueberryIceCream = new BlueberryAdapter(new IceCream());

    // 给我来个蓝莓巧克力冰淇淋~~
    AbstractIceCream bb_ch_iceCream = new BlueberryAdapter(new ChocolateAdapter(new IceCream()));

    // 来了一个巧克力超级粉丝说,我要加3层巧克力~~
    AbstractIceCream lot_of_chocolate_iceCream = new ChocolateAdapter(
      new ChocolateAdapter(new ChocolateAdapter(new IceCream())));

    // 然后算帐看看,你猜这些冰淇淋分别要多少钱呢...
    System.out.println(blueberryIceCream.getPrice());
    System.out.println(bb_ch_iceCream.getPrice());
    System.out.println(lot_of_chocolate_iceCream.getPrice());
  }
}

实例二

 现在需要一个汉堡,主体是鸡腿堡,可以选择添加生菜、酱、辣椒等等许多其他的配料,这种情况下就可以使用装饰者模式。

汉堡基类(被装饰者)

package decorator;    

public abstract class Humburger 
{
  protected  String name;        
  public String getName()
  {    
    return name;    
  }    

  public abstract double getPrice();  
}

鸡腿堡类(被装饰者的初始状态,有些自己的简单装饰)

package decorator;    

public class ChickenBurger extends Humburger 
{      
  public ChickenBurger()
  {    
    name = "鸡腿堡";    
  }    

  @Override    
    public double getPrice() 
  {    
    return 10;    
  }    
}

配料的基类(装饰者,用来对汉堡进行多层装饰,每层装饰增加一些配料,相当于上面Decorator)

package decorator;    

public abstract class Condiment extends Humburger 
{
  public abstract String getName();
}

生菜(装饰者的第一层)

package decorator;    

public class Lettuce extends Condiment 
{
  Humburger humburger;
  public Lettuce(Humburger humburger)
  {    
    this.humburger = humburger;    
  }    

  @Override    
    public String getName() 
  {    
      return humburger.getName()+" 加生菜";    
  }    

  @Override    
    public double getPrice() 
  {    
      return humburger.getPrice()+1.5;    
  }
}

辣椒(装饰者的第二层)

package decorator;    

public class Chilli extends Condiment 
{
  Humburger humburger;    

  public Chilli(Humburger humburger)
  {    
    this.humburger = humburger;
  }    

  @Override    
    public String getName() 
  {    
      return humburger.getName()+" 加辣椒";    
  }    

  @Override    
    public double getPrice() 
  {    
      return humburger.getPrice();  //辣椒是免费的哦    
  }
}

测试类

package decorator;    

public class Test 
{   
  public static void main(String[] args) 
  {    
    Humburger humburger = new ChickenBurger();    
    System.out.println(humburger.getName()+"  价钱:"+humburger.getPrice());    

    Lettuce lettuce = new Lettuce(humburger);    
    System.out.println(lettuce.getName()+"  价钱:"+lettuce.getPrice());    

    Chilli chilli = new Chilli(humburger);    
    System.out.println(chilli.getName()+"  价钱:"+chilli.getPrice());    

    Chilli chilli2 = new Chilli(lettuce);    
    System.out.println(chilli2.getName()+"  价钱:"+chilli2.getPrice());    
  }
}

输出

鸡腿堡  价钱:10.0    
鸡腿堡 加生菜  价钱:11.5    
鸡腿堡 加辣椒  价钱:10.0    
鸡腿堡 加生菜 加辣椒  价钱:11.5

 

 

 

 

 

 

 

 

参考 http://blog.csdn.net/jason0539/article/details/22713711

装饰模式 Decorator

标签:

原文地址:http://www.cnblogs.com/happykoukou/p/5413904.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!