设计模式之装饰者模式

装饰者模式  Decorator

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

适用性:当采用类继承的方式会造成类爆炸的情况。如本文的例子中,基本饮料(被装饰者)可能有茶、水、牛奶等等、可以添加的(装饰者)有糖、果肉、珍珠等。

    如果通过继承的方式,为每一种类型的奶茶设计一种类会造成类爆炸,同时也不利于后期的扩展(如又添加一种基本饮料豆浆的情况),此时通过装饰者模式可以很好的解决问题。

    装饰者模式本质是一种组合的思想(不同于继承的思想),多组合少继承。利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为。然而,如果能够利用组合的做法扩展对象的行为,就可以在运行时动态地进行扩展。

装饰者模式的主要组成部分:抽象被装饰者、具体被装饰者、抽象装饰者、具体装饰者。(当只有一个具体被装饰者、一个具体装饰者,其对应的抽象类可以省略)。

装饰者模式类图:

装饰者模式要点:

1 多种具体被装饰者(主体类)抽象出一个抽象被装饰类,后面通过多态,动态传递具体对象。

2 抽象装饰类继承抽象被装饰者(保持接口);要求传入被装饰者(使用父类应用、protected修饰);

3 多种具体装饰者抽象出一个抽象装饰类。

4 具体装饰者中,可以添加新方法,可以重写方法;需要使用被装饰者方法的地方用传入的被装饰者引用。

装饰者模式的基本代码:

/**
 * 被装饰抽象类——基本饮料
 *
 * 作用:当具体的被装饰类有多种时,抽象提出该抽象类,用于后面实现多态。
 */
public abstract class BaseDrink {
    public abstract int calculate();
    public abstract void display();
}
/**
 * 具体的被装饰者类—— Water类
 * 继承抽象的被装饰者类,并实现其中的抽象方法。
 */

public class Water extends BaseDrink{
    @Override
    public int calculate() {
        return 3;
    }

    @Override
    public void display() {
        System.out.println("water");
    }
}
/**
 * 具体的被装饰者类—— Tea类
 * 继承抽象的被装饰者类,并实现其中的抽象方法。
 */

public class Tea extends BaseDrink{
    @Override
    public int calculate() {
        return 5;
    }

    @Override
    public void display() {
        System.out.println("Tea");
    }
}
/**
 * 抽象装饰者类——Decorator
 * 要点:1.抽象装饰者类中继承该抽象类以保持接口规范
 *      2.包含该抽象类的引用以通过多态的方式对多种被装饰者类进行装饰。
 */

public abstract class Decorator extends BaseDrink{  //继承,保持接口
    protected BaseDrink bd;  //引用,多态

    public Decorator(BaseDrink bd) {
        this.bd = bd;
    }

    @Override
    public int calculate() {
        return bd.calculate();
    }

    @Override
    public void display() {
        bd.display();
    }
}
/**
 * 装饰者类  果肉
 */
public class FleshDecorator extends Decorator{
    public FleshDecorator(BaseDrink bd) {
        super(bd);
    }

    @Override
    public int calculate() {
        return super.calculate() + 2;
    }

    @Override
    public void display() {
        super.display();
        System.out.println("+ flesh");
    }
}


/**
* 装饰者类 糖
*/
public class SugarDecorator extends Decorator{
public SugarDecorator(BaseDrink bd) {
super(bd);
}

@Override
public int calculate() {
return super.calculate()+1;
}

@Override
public void display() {
bd.display();
System.out.println("+ sugar");
}

public void addMoreSugar(){
System.out.println("add more sugar");
}
}
 
/**
 * 测试用例
 */
public class TestCase {
    public static void main(String[] args) {
        BaseDrink water = new Water();
        SugarDecorator sugarWater = new SugarDecorator(water);
        sugarWater.addMoreSugar();
        sugarWater.display();
        System.out.println(sugarWater.calculate());
        System.out.println("=========================");
        BaseDrink tea = new Tea();
        FleshDecorator fleshTea = new FleshDecorator(tea);
        fleshTea.display();
        System.out.println(fleshTea.calculate());
    }
}
//结果

F:\deaIC-2019.1.3-jbr11.win\jre64\bin\java.exe -javaagent:F:\deaIC-2019.1.3-jbr11.win\lib\idea_rt.jar=7425:F:\deaIC-2019.1.3-jbr11.win\bin -Dfile.encoding=UTF-8 -classpath E:\eclipse-workspace\decoratorDemo\out\production\decoratorDemo TestCase
add more sugar
water
+ sugar
4
=========================
Tea
+ flesh
7

 

posted @ 2019-06-18 17:48  由走啦啦啦  阅读(4376)  评论(1编辑  收藏  举报