装饰者模式【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三种组合,而且在编译
阶段就规定要了可能的所有组合方式,要达到前面的效果,就必须有七个装饰者类。
最显著的区别:装饰者模式只需定义好几个基本装饰元素,最终的装饰结果由这些“装饰元素”
在运行期任意组合。