java设计模式-装饰者模式

百般思念 提交于 2020-02-09 05:27:05

 

这个模式花费了挺长时间,开始有点难理解,其实就是

定义:动态给一个对象添加一些额外的职责,就象在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活。
设计初衷:通常可以使用继承来实现功能的拓展,如果这些需要拓展的功能的种类很繁多,那么势必生成很多子类,增加系统的复杂性,同时,使用继承实现功能拓展,我们必须可预见这些拓展功能,这些功能是编译时就确定了,是静态的。

 

 要点:装饰者与被装饰者拥有共同的超类,继承的目的是继承类型,而不是行为

以点咖啡为例:

    我们在点咖啡的时候通常会有这样的情况:

      点了不同的咖啡会有不同的价格,此时我们需要一个咖啡的基类,不同的咖啡重写基类的cost()方法来实现自己的价格,但有时候我们点咖啡的时候会需要添加一些额外的调料,这个时候价格就变了,而这些额外的调料现在又是不确定的,如果提供过多的set()和get()方法来进行调料的添加又会出现新的问题,如果后续推出茶,汽水之类的饮料时,我们从基类那里继承过来很多没用的set和get方法

     所以在这里我们采用不一样的做法:以饮料为主体,然后在运行时以调料来“装饰”饮料,比如说顾客想要 加摩卡和加奶泡的深培咖啡,那么,要做的是:

    1:拿一个深培咖啡对象(DarkRoast)

    2:以摩卡(Mocha)对象装饰它

    3:以奶泡(Whip)对象装饰它

    4:调用cost()方法,并依赖委托(delegate)将调料的价钱加上去

    最后在运行的时候:首先,调用最外圈装饰着Whip的cost()方法,Whip调用Mocha的cost()方法,Mocha调用DarkRoast的cost()方法,DarkRoast返回它的价钱$0.99,Mocha在DarkRoast的结果上加上自己的价钱$0.20,返回新的价钱$1.19。Whip在Mocha的返回结果上加上自己的价钱$0.10,然后返回最后结果$1.29。

 装饰者模式具有以下特点:

     装饰者和被装饰者对象具有相同的超类型。

      你可以用一个或多个装饰者包装一个对象。

      既然装饰者和被装饰对象有相同的超类型,所以在任何需要原始的对象(被包装的)的场合,可以用装饰过的对象替代它。

      装饰者可以在所委托被装饰者的行为之前与/或之后,加上自己的行为,以达到特定的目的。

      对象可以在任何时候被装饰,所以在运行时动态的,不限量的用你喜欢的装饰者来装饰对象。

装饰者模式的说明:

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

/*
 * create by zxf 2016/2/18
 * 这个是所有饮料以及调料的基类
 * 饮料类
 */
public abstract class Beverage {
   String description="Unknow Beverage";
   public String getDescription(){
  return description;
   }
   public abstract double cost();
}

  然后添加调味品装饰者基类

  /*
 * create by zxf 2016/2/18
 * 这是所有调料的基类
 * 调味品装饰
 */
public abstract class CondimentDecorator extends Beverage{
public abstract String getDescription();

创建一种咖啡:

/*
 * 浓缩咖啡 继承自
 */
public class Espresso extends Beverage{

public Espresso() {
description="Espresso";
}


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

创建以下调味品装饰类:

    /*
 * create by zxf 2016/2/18
 * 摩卡装饰类 调味品
 */
public class Mocha extends CondimentDecorator{


private Beverage beverage;
public Mocha(Beverage beverage) {
this.beverage=beverage;
}


@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();
}
}

/*
 * create by zxf 2016/2/18
 * 豆浆调味品  装饰者
 */
public class Soy extends CondimentDecorator{
private 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();
}

}

/*
 * create by zxf 2016/1/18
 * 奶泡装饰者 
 */
public class Whip extends CondimentDecorator{
private 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();
}
}

然后调用如下代码:

  //新点一杯浓缩咖啡
Beverage beverage=new Espresso();
beverage=new Mocha(beverage);//添加摩卡 使用摩卡装饰
beverage=new Whip(beverage);//添加奶泡    使用奶泡装饰
beverage=new Soy(beverage);//添加豆浆      使用豆浆装饰
System.out.println(beverage.getDescription()+";价钱为:"+beverage.cost());

结果如下:

    Espresso, Mocha, Whip, Soy;价钱为:2.44

     

    我们在点咖啡的时候

   

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!