[设计模式]装饰者模式(decorator)

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

2、满足OO设计原则——开放-关闭原则:类应该对扩展开放,对修改关闭。

注:装饰者模式是一个简单的能够实现开放-关闭原则的设计模式

3、优点:

  • 能够遵循开放-关闭原则,使系统更有弹性
  • 组合和委托可以用于在运行时动态地加上新的行为
  • 装饰者类反映出被装饰的组件类型(事实上,它们具有相同的类型,都经过接口或集成实现)
  • 装饰者可以再被装饰者的行为前面与/或后面加上自己的行为,甚至将被装饰者的行为整个取代掉,而达到特定的目的。

4、缺点:装饰者会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂。

5、具体实现(完整代码保存在github上):

  • 抽象组件类:
//饮料超类
public abstract class Beverage{
    String description = "Unknown Beverage";
    public String getDescription(){
        return description;
    }

    public abstract double cost();
}
  • 具体组件类:
//饮料:深焙
public class DarkRoast extends Beverage{
    public DarkRoast(){
        description = "DarkRoast";
    }
    public double cost(){
        return .99;
    }
}

//饮料:低咖啡因
public class Decaf extends Beverage{
    public Decaf(){
        description = "Decaf";
    }
    public double cost(){
        return 1.05;
    }
}

//饮料:浓缩
public class Espresso extends Beverage{
    public Espresso(){
        description = "Espresso";
    }
    public double cost(){
        return 1.99;
    }
}

//饮料:综合
public class HouseBlend extends Beverage{
    public HouseBlend(){
        description = "House Blend coffee";
    }
    public double cost(){
        return .89;
    }
}
  • 抽象装饰者类:
//调料都继承自这里
public abstract class CondimentDecorator extends Beverage{
    public abstract String getDescription();    
}
  • 具体装饰者类:
//调料:牛奶
public class Milk extends CondimentDecorator{
    Beverage beverage;
    public Milk(Beverage beverage){
        this.beverage = beverage;
    }
    public String getDescription(){
        return beverage.getDescription() + ",Milk";
    }
    public double cost(){
        return .10 + beverage.cost();
    }
}

//调料:摩卡
public class Mocha extends CondimentDecorator{
    Beverage beverage;
    public Mocha(Beverage beverage){
        this.beverage = beverage;
    }
    public String getDescription(){
        return beverage.getDescription() + ",Mocha";
    }
    public double cost(){
        return .20 + beverage.cost();
    }
}

//调料:豆浆
public class Soy extends CondimentDecorator{
    Beverage beverage;
    public Soy(Beverage beverage){
        this.beverage = beverage;
    }
    public String getDescription(){
        return beverage.getDescription() + ",Soy";
    }
    public double cost(){
        return .15 + beverage.cost();
    }

//调料:奶泡
public class Whip extends CondimentDecorator{
    Beverage beverage;
    public Whip(Beverage beverage){
        this.beverage = beverage;
    }
    public String getDescription(){
        return beverage.getDescription() + ",Whip";
    }
    public double cost(){
        return .10 + beverage.cost();
    }
}
  • 测试:
public class StarbuzzCoffee{
    public static void main(String args[]){
        Beverage beverage = new Espresso();
        System.out.println(beverage.getDescription() + " $" + beverage.cost());

        Beverage beverage2 = new DarkRoast();
        beverage2 = new Mocha(beverage2);
        beverage2 = new Mocha(beverage2);
        beverage2 = new Whip(beverage2);
        System.out.println(beverage2.getDescription() + " $" + beverage2.cost());

        Beverage beverage3 = new HouseBlend();
        beverage3 = new Soy(beverage3);
        beverage3 = new Mocha(beverage3);
        beverage3 = new Whip(beverage3);
        System.out.println(beverage3.getDescription() + " $" + beverage3.cost());

    }
}

 

运行结果如下图所示:

 

参考资料

[1] head first 设计模式

posted @ 2020-03-12 16:22  justDoIT&  阅读(163)  评论(0)    收藏  举报