装饰者模式【java版】

一、基本结构

1.层次一:原始抽象类

   抽象类:Cake

abstract class Cake {
protected String description="Unknown Cake";

public abstract void printDescription();//抽象方法必须指定为abstract类型

}

2.层次二:具体实现者、装饰者抽象类

  具体实现者1:WhiteCake

public class WhiteCake extends Cake {

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

@Override
public void printDescription() {

System.out.println("制作最简单的蛋糕,蛋糕名为:"+description.toString());
}

}

  具体实现者2:YellowCake

public class YellowCake extends Cake{
public YellowCake() {
description="YellowCake";
}

@Override
public void printDescription() {

System.out.println("制作最简单的蛋糕,蛋糕名为:"+description.toString());
}

}

  装饰者抽象类:CakeDecorator

public abstract class CakeDecorator extends Cake {

@Override
public abstract void printDescription();

}

说明之所以要定义一个并未进行任何实现的“装饰者抽象类”,是由于:如果装饰类,

   直接实现接口并添加装饰,则会表现为“基本实现类”和“装饰类”位于同一层上,显然

   不符合大家通常的理解习惯。

         此种设计思想可参照java I/O类图。

3.层次三:具体装饰者

  具体装饰者A:MilkCake

public class MilkCake extends CakeDecorator {

Cake cake;

public MilkCake(Cake cake) {
this.cake=cake;
}

@Override
public void printDescription() {
this.cake.printDescription();
addMilk();
}

private void addMilk(){//新增加的装饰性的方法
System.out.println("添加装饰A:Milk");
}
}

  具体装饰者B:ChocolateCake

public class ChocolateCake extends CakeDecorator {

Cake cake;

public ChocolateCake(Cake cake) {
this.cake=cake;
}

@Override
public void printDescription() {
this.cake.printDescription();
addChocolate();
}

private void addChocolate(){//新增加的装饰性的方法
System.out.println("添加装饰B:Chocolate");
}
}

  具体装饰者C:FruitCake

public class FruitCake extends CakeDecorator {

Cake cake;

public FruitCake(Cake cake) {
this.cake=cake;
}

@Override
public void printDescription() {
this.cake.printDescription();
addFruit();

}

private void addFruit(){//新增加的装饰性的方法
System.out.println("添加装饰C: Fruit");
}
}


二、测试

    测试代码:

public class Main {

public static void main(String[] args) {
System.out.println("开始测试装饰者模式。。。");

Cake theCake=new WhiteCake();

//测试“被装饰者”
theCake.printDescription();
System.out.println("");

//测试单重“装饰者”
CakeDecorator theSingleCakeDecorator=new MilkCake(theCake);
theSingleCakeDecorator.printDescription();
System.out.println("");

//测试多重“装饰者”
CakeDecorator theMultiCakeDecorator=new FruitCake(new ChocolateCake(new MilkCake(theCake)));
theMultiCakeDecorator.printDescription();
System.out.println("");
}

}

    运行结果:

   说明:如何体现动态加载,而不是在编译阶段就确定好实例的所有特征?

        凡是new出实例都是在“运行阶段”进行的,假如有三个装饰物: 装饰物A,装饰物B, 装饰物C
       装饰者模式:三个装饰者类,使用时任意组合,可以有A,B,C,AB,AC,BC,ABC共7种组合。
       传统继承的方式:三个装饰者类,使用时实例化子类,只有A,B,C三种组合,而且在编译

                  阶段就规定要了可能的所有组合方式,要达到前面的效果,就必须有七个装饰者类
       最显著的区别:装饰者模式只需定义好几个基本装饰元素,最终的装饰结果由这些“装饰元素”

                  在运行期任意组合。


 

        

原文地址:https://www.cnblogs.com/edisonfeng/p/2300817.html