结构型设计模式,动态地为对象添加额外的职责。通过组合而非继承的方式扩展功能,提供比继承更灵活的替代方案。
✅ 需要动态/透明地给对象添加功能
✅ 需要撤销附加功能时
✅ 无法通过继承扩展功能(final类)
✅ 需要组合多个可选功能
✅ 避免"子类爆炸"问题
角色 | 说明 |
---|---|
Component | 抽象组件,定义被装饰对象的接口 |
ConcreteComponent | 具体组件,实现基本功能 |
Decorator | 装饰者抽象类,持有组件引用并实现组件接口 |
ConcreteDecorator | 具体装饰者,添加额外功能 |
// 抽象组件
public interface Coffee {
double getCost();
String getDescription();
}
// 具体组件
public class SimpleCoffee implements Coffee {
public double getCost() {
return 2.0;
}
public String getDescription() {
return "咖啡";
}
}
// 抽象装饰者
public abstract class CoffeeDecorator implements Coffee {
protected Coffee decoratedCoffee;
public CoffeeDecorator(Coffee coffee) {
this.decoratedCoffee = coffee;
}
public double getCost() {
return decoratedCoffee.getCost();
}
public String getDescription() {
return decoratedCoffee.getDescription();
}
}
// 具体装饰者
public class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
public double getCost() {
return super.getCost() + 0.5;
}
public String getDescription() {
return super.getDescription() + " + 牛奶";
}
}
public class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee coffee) {
super(coffee);
}
public double getCost() {
return super.getCost() + 0.2;
}
public String getDescription() {
return super.getDescription() + " + 糖";
}
}
// 客户端
public class Client {
public static void main(String[] args) {
Coffee coffee = new SimpleCoffee();
coffee = new MilkDecorator(coffee);
coffee = new SugarDecorator(coffee);
System.out.println("总价: $" + coffee.getCost());
System.out.println("描述: " + coffee.getDescription());
/* 输出:
总价: $2.7
描述: 咖啡 + 牛奶 + 糖 */
}
}
Coffee coffee = new SugarDecorator(new MilkDecorator(new SimpleCoffee()));
✔️ 优点:
❌ 缺点:
模式 | 目的 | 关键区别 |
---|---|---|
适配器模式 | 接口转换 | 改变对象接口 |
代理模式 | 控制访问 | 保持接口相同 |
组合模式 | 树形结构处理 | 装饰者是被组合对象的包装 |
责任链模式 | 请求传递 | 装饰者可以终止处理过程 |
new BufferedInputStream(new FileInputStream("file.txt"));
public class LoggingHttpRequest extends HttpServletRequestWrapper {
public LoggingHttpRequest(HttpServletRequest request) {
super(request);
}
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
System.out.println("获取参数: " + name + "=" + value);
return value;
}
@Override
public Part getPart(String name) throws IOException, ServletException {
Part part = super.getPart(name);
System.out.println("上传文件: " + name + " size=" + part.getSize());
return part;
}
}
// 在Filter中使用
public class LoggingFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest wrappedRequest = new LoggingHttpRequest((HttpServletRequest) request);
chain.doFilter(wrappedRequest, response);
}
}
设计原则体现:
- 开闭原则(OCP):不修改原有类即可扩展新功能
- 组合优于继承(Composite Reuse Principle):使用对象组合代替类继承
- 单一职责原则(SRP):每个装饰者只关注单一功能增强
通过装饰者模式,可以实现灵活的功能扩展,特别适合需要动态组合多种可选功能的场景。该模式在框架设计和基础库开发中应用广泛,是处理功能叠加问题的经典解决方案。