设计模式之(三)——装饰者模式(Decorator Pattern)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/iaiti/article/details/82215463

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

很多文章也是拿了书上的例子来讲,同时写到,有的调料装饰者都必须实现 getDescription() 大家可以先考虑下,稍后我们会说。最后都是没说,还有思考的同时你也应该会抛出一些问题,这样能让你对该模式的印象更加的深刻。

/**
 * 饮料
 */
public abstract class Beverage {
     public String description = "unknown";
     public String getDescription(){
            return description;
     }
     public abstract double cost();
}
/**
 *  装饰者
 */
public abstract class Condiment extends Beverage{

     @Override
     public abstract String getDescription();
}
/**
 * 浓咖啡,被装饰者
 */
public class Latte extends Beverage{

     @Override
     public String getDescription() {
            return "Latte";
     }

     @Override
     public double cost() {
            return 1.0;
     }

}
/**
 * 具体的装饰者
 */
public class Milk extends Condiment {
     public Beverage beverage;
     public double milkcost = 0.5;
     public Milk(Beverage beverage){
            this. beverage = beverage;
     }
     
     @Override
     public String getDescription () {
            return "milk add:"+ beverage.getDescription();
     }

     @Override
     public double cost () {
            return milkcost+ beverage.cost();
     }

}
/**
 * 具体装饰者
 */
public class Whip extends Beverage {
    public Beverage beverage;
    public double whipcost = 0.2;

    public Whip(Beverage beverage) {
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        return "whip add:" + beverage.getDescription();
    }

    @Override
    public double cost () {
    return whipcost+ beverage.cost();
}
public class TestA {
     public static void main(String[] args) {
           Beverage b = new Espresso();
            Condiment c = new Milk(b);
           System. out.println(c.getDescription());
           System. out.println(c.cost());
     }
}
public class TestB {
     public static void main(String[] args) {
           Beverage b = new Espresso();
           System. out.println(b.cost()+ " "+b.getDescription());
           Beverage c = new Milk(b); //第一个装饰,把装饰者当成了构造器参数
           c = new Milk(c);//第二个装饰
           c = new Whip(c);//第三个装饰
           System. out.println(c.cost()+ " "+c.getDescription());
     }
}

TestA只是很简单的一层装饰,TestB才是装饰者的核心所在。

这样能一层嵌一层。这才是核心。但是没搞懂,为什么装饰器,实现的是Condiment。

而Condiment本身就是继承Beverage。我的Milk和Whip直接继承Beverage也是可以的。

为什么装饰者都去先继承了Decorator,问过有经验的人,给了我很生动的比喻,具体的装饰者就是稀饭,炒饭,干饭,中间层是饭。再结合自己所思考的,如果饭继承是食物,那么你用稀饭直接去继承食物也是没问题的。中间层是给了一层清晰的分类。专门用来区分装饰者。你看Milk和Whip的继承就明显看出这两者是装饰者。所以中间层的目的在此,是对所有装饰者集合的一层抽象,暂时想到的是这些。

由IO流的使用你就可以发现模式的缺点,装饰者的设计会导致有很多很多类,使用api的时候不清晰。但是可以通过对象之前的嵌入组合扩展出很多行为,这也是装饰者模式最大的优点。

猜你喜欢

转载自blog.csdn.net/iaiti/article/details/82215463