目录
前言
java常用的设计模式分类:创建型、结构型、行为型。
分类如下:
装饰器模式(Decorator Pattern)是结构型设计模式之一。
从之前介绍代理模式,装饰器模式和代理模式的区别如下:
代理是全权代理,目标根本不对外,全部由代理类来完成;
装饰是增强,是辅助,目标仍然可以自行对外提供服务,装饰器只起增强作用。
装饰器模式强调的是:增强、新增行为;
代理模式强调的是:对代理的对象施加控制,但不对对象本身的功能进行增强。
装饰器模式:生效的对象还是原本的对象;
代理模式:生效的是新的对象(代理对象)。
1、定义介绍
1.1、定义
它的核心思想是:不改变原有类的情况下,动态地给对象扩展功能,并且扩展后的对象依然可以替换原有对象(遵循开闭原则)。
1.2、装饰器模式结构图
- 抽象组件(Component):定义对象的接口。
- 具体组件(ConcreteComponent):被装饰的原始对象。
- 抽象装饰器(Decorator):实现组件接口,持有一个组件的引用。
- 具体装饰器(ConcreteDecorator):扩展功能,并委托给原始对象。
2、实现
以咖啡和调料为例(经典例子):
1、抽象组件
// 抽象组件
public interface Coffee {
String getDescription();
double getCost();
}
2、具体组件
// 具体组件
public class SimpleCoffee implements Coffee {
@Override
public String getDescription() {
return "Simple Coffee";
}
@Override
public double getCost() {
return 5.0;
}
}
3、抽象装饰器
// 抽象装饰器
public abstract class CoffeeDecorator implements Coffee {
protected Coffee decoratedCoffee;
public CoffeeDecorator(Coffee coffee) {
this.decoratedCoffee = coffee;
}
@Override
public String getDescription() {
return decoratedCoffee.getDescription();
}
@Override
public double getCost() {
return decoratedCoffee.getCost();
}
}
4、具体装饰器
eg: 加糖,加牛奶,如下所示:
// 加糖
public class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return super.getDescription() + ", Sugar";
}
@Override
public double getCost() {
return super.getCost() + 1.0; // 加1元
}
}
// 加牛奶
public class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public String getDescription() {
return super.getDescription() + ", Milk";
}
@Override
public double getCost() {
return super.getCost() + 2.0; // 加2元
}
}
5、使用示例
如下所示:
public class DecoratorDemo {
public static void main(String[] args) {
Coffee coffee = new SimpleCoffee();
System.out.println(coffee.getDescription() + " $" + coffee.getCost());
// 加糖
coffee = new SugarDecorator(coffee);
System.out.println(coffee.getDescription() + " $" + coffee.getCost());
// 再加牛奶
coffee = new MilkDecorator(coffee);
System.out.println(coffee.getDescription() + " $" + coffee.getCost());
}
}
输出结果:
Simple Coffee $5.0
Simple Coffee, Sugar $6.0
Simple Coffee, Sugar, Milk $8.0
3、典型应用场景
1、Java IO流
(InputStream/OutputStream/Reader/Writer) 就是装饰器模式的标准实践。
// 基本功能:读文件
InputStream in = new FileInputStream("a.txt");
// 装饰:加缓冲
InputStream bin = new BufferedInputStream(in);
// 装饰:支持读基本类型
InputStream din = new DataInputStream(bin);
需要“动态地”增加或者撤销对象的某些功能的时候。
4、优缺点
1、优点:
- 比继承更灵活(不会导致类爆炸式增长)
- 可以动态地扩展功能,互不干扰
2、缺点:
- 系统中会产生许多小对象,理解和调试略复杂
总结:
对比策略模式、装饰器模式、适配器模式的区别:
参考文章: