Java设计模式系列之装饰者模式

装饰者模式的定义

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

装饰者模式的UML类图

 

 

一般来说装饰者模式有下面几个参与者:

  • Component:装饰者和被装饰者共同的父类,是一个接口或者抽象类,用来定义基本行为
  • ConcreteComponent:定义具体对象,即被装饰者
  • Decorator:抽象装饰者,继承自Component,从外类来扩展ConcreteComponent。对于ConcreteComponent来说,不需要知道Decorator的存在,Decorator是一个接口或抽象类
  • ConcreteDecorator:具体装饰者,用于扩展ConcreteComponent

注:装饰者和被装饰者对象有相同的超类型,因为装饰者和被装饰者必须是一样的类型,这里利用继承是为了达到类型匹配,而不是利用继承获得行为

利用继承设计子类,只能在编译时静态决定,并且所有子类都会继承相同的行为;利用组合的做法扩展对象,就可以在运行时动态的进行扩展。装饰者模式遵循开放-关闭原则:类应该对扩展开放,对修改关闭利用装饰者,我们可以实现新的装饰者增加新的行为而不用修改现有代码,而如果单纯依赖继承,每当需要新行为时,还得修改现有的代码。

example:

/**
 * @author yaoshw
 */
public class TestMyIdea {
    public static void main(String[] args) {

        //不添加任何调料的饮料A
        Beverage beverage = new APart();
        System.out.println("Apart:" + beverage.getDescription() + "," + beverage.cost());

        //添加摩卡调料的饮料B
        Beverage beverage1 = new Mocha(new BPart());
        System.out.println("Bpart:" + beverage1.getDescription() + "," + beverage1.cost());

        //添加双份摩卡的饮料C

        Beverage beverage2 = new Mocha(new Mocha(new CPart()));
        System.out.println("Cpart:" + beverage2.getDescription() + "," + beverage2.cost());

        //添加一份摩卡、一份豆浆的饮料D

        Beverage beverage3 = new Soy(new Mocha(new DPart()));
        System.out.println("Dpart:" + beverage3.getDescription() + "," + beverage3.cost());


    }
}

/**
 * 抽象类,相当于Component:cost方法和getDescription方法
 */
abstract class Beverage {

    String description = "UnKnownBeverage";

    public String getDescription() {
        return description;
    }

    public abstract double cost();
}

abstract class CondimentDerector extends Beverage {
    @Override
    public abstract String getDescription();
}

/**
 * 具体装饰者:摩卡
 */
class Mocha extends CondimentDerector {

    /**
     * 保留基类的引用,以便于组合装饰者行为
     */
    Beverage beverage;

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

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

    @Override
    public String getDescription() {
        return beverage.getDescription() + ",monka";
    }
}

/**
 * 具体装饰者:豆浆
 */
class Soy extends CondimentDerector {

    Beverage beverage;

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

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

    @Override
    public String getDescription() {
        return beverage.getDescription() + "soy";
    }
}

/**
 * 调料A
 */
class APart extends Beverage {

    public APart() {
        description = "Apart";
    }

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

/**
 * 调料B
 */
class BPart extends Beverage {

    public BPart() {
        description = "Bpart";
    }

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

/**
 * 调料C
 */
class CPart extends Beverage {

    public CPart() {
        description = "Cpart";
    }

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

/**
 * 调料D
 */
class DPart extends Beverage {

    public DPart() {
        description = "Dpart";
    }

    @Override
    public double cost() {
        return 22.5;
    }
}
posted @ 2019-01-27 11:18  菜鸟奋斗史  阅读(523)  评论(0编辑  收藏  举报