一.定义
在不改变原有对象行为的基础上,扩展对象的功能。
属于结构型模式
二.通用写法
一般来说装饰器模式有这么几个功能
Component:抽象组件
ConcreteComponent:具体的组件,也就是被装饰的对象
Decorator:抽象装饰器
ConcreteComponent:具体的装饰器
下面来看一个简单的例子
买煎饼的时候可以加鸡蛋可以加火腿,也可以什么都不加。我们用装饰器模式来模式一下这个场景
首先定义一个抽象组件
public abstract class Pancake {
protected abstract String getName();
protected abstract Double getPrice();
}
定义一个具体的组件,实现抽象组件的方法
public class BasePancake extends Pancake{
protected String getName() {
return "煎饼";
}
protected Double getPrice() {
return 5d;
}
}
然后我们定义一个抽象的装饰器,这个抽象装饰器有个特点:它一定是有一个抽象组件作为参数的构造方法
public abstract class PancakeDecorator extends Pancake{
private Pancake pancake;
public PancakeDecorator(Pancake pancake) {
this.pancake = pancake;
}
public String getName() {
return this.pancake.getName();
}
public Double getPrice() {
return this.pancake.getPrice();
}
}
具体的装饰器,EggDecorator,加鸡蛋的煎饼
public class EggDecorator extends PancakeDecorator{
private Pancake pancake;
public EggDecorator(Pancake pancake) {
super(pancake);
}
public String getName() {
return super.getName() + "+一个鸡蛋";
}
public Double getPrice() {
return super.getPrice() + 1d;
}
}
具体的装饰器,SausageDecorator,加香肠的煎饼
public class SausageDecorator extends PancakeDecorator{
public SausageDecorator(Pancake pancake) {
super(pancake);
}
@Override
public String getName() {
return super.getName() + "+一个香肠";
}
@Override
public Double getPrice() {
return super.getPrice() + 2d;
}
}
测试类:
public class Test {
public static void main(String[] args) {
Pancake pancake = new BasePancake();
System.out.println(pancake.getName() + ",总价:" + pancake.getPrice());
Pancake pancakeEgg = new EggDecorator(pancake);
System.out.println(pancakeEgg.getName() + ",总价:" + pancakeEgg.getPrice());
Pancake pancakeSausage = new SausageDecorator(pancakeEgg);
System.out.println(pancakeSausage.getName() + ",总价:" + pancakeSausage.getPrice());
}
}
输出
我们通过使用装饰器模式,在不改变原有对象行为的基础上,给它增加了其他功能,使得一个煎饼可以加鸡蛋加火腿,也可以再定义其他的类加其他的材料
三.装饰器模式的优缺点
优点:符合开闭原则,代码易扩展,耦合度低
缺点:装饰器类容易变多,给代码阅读和维护带来挑战
四.装饰器模式在源码中的应用
FileInputStream、BufferedInputStream、Cache
五.装饰器模式和代理模式的区别
装饰器模式也是一种静态代理模式,但它强调功能的扩展,而代理模式强调功能的增强。