装饰器模式是一种结构型设计模式,允许你动态地给一个对象添加额外的功能。它是通过创建一个包装对象(装饰器),来包裹原始的对象,从而在不改变其结构的情况下,动态地扩展对象的行为。
结构
- 组件接口(Component): 定义了具体组件和装饰器的公共接口。
public interface Component {
void operation();
}
- 具体组件类(Concrete Component): 实现了组件接口,是被装饰的具体对象。
public class ConcreteComponent implements Component {
public void operation() {
System.out.println("Concrete Component operation.");
}
}
- 装饰器抽象类(Decorator): 继承了组件接口,包含一个组件的引用,以及定义了装饰器的接口。
public abstract class Decorator implements Component {
protected Component component;
public Decorator(Component component) {
this.component = component;
}
public void operation() {
component.operation();
}
}
- 具体装饰器类(Concrete Decorator): 继承了装饰器抽象类,实现了具体的装饰逻辑。
public class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
public void operation() {
super.operation();
System.out.println("Concrete Decorator operation.");
}
}
优点和缺点
优点:
- 动态扩展功能: 装饰器模式允许你在不修改现有代码的情况下,动态地扩展一个对象的功能。
- 遵循开闭原则: 可以增加新的装饰器类而不需要修改现有的代码,符合开闭原则。
- 组件具有透明性: 使用装饰器模式可以保持组件的接口和实现对客户端透明,客户端不需要知道具体的装饰器类。
缺点:
- 类的数量增加: 引入装饰器会增加系统中类的数量,可能会使得系统变得更加复杂。
示例
以下是一个装饰器模式的示例,通过装饰器给一个文本添加样式:
// 组件接口
public interface Text {
String getContent();
}
// 具体组件类
public class PlainText implements Text {
private String content;
public PlainText(String content) {
this.content = content;
}
public String getContent() {
return content;
}
}
// 装饰器抽象类
public abstract class TextDecorator implements Text {
protected Text text;
public TextDecorator(Text text) {
this.text = text;
}
public String getContent() {
return text.getContent();
}
}
// 具体装饰器类
public class BoldDecorator extends TextDecorator {
public BoldDecorator(Text text) {
super(text);
}
public String getContent() {
return "<b>" + super.getContent() + "</b>";
}
}
public class ItalicDecorator extends TextDecorator {
public ItalicDecorator(Text text) {
super(text);
}
public String getContent() {
return "<i>" + super.getContent() + "</i>";
}
}
// 客户端代码
public class Main {
public static void main(String[] args) {
Text text = new PlainText("Hello, World!");
System.out.println("Original Text: " + text.getContent());
Text boldText = new BoldDecorator(text);
System.out.println("Bold Text: " + boldText.getContent());
Text italicText = new ItalicDecorator(text);
System.out.println("Italic Text: " + italicText.getContent());
Text boldItalicText = new BoldDecorator(new ItalicDecorator(text));
System.out.println("Bold and Italic Text: " + boldItalicText.getContent());
}
}
在这个例子中,PlainText 是具体的组件类,TextDecorator 是装饰器抽象类,BoldDecorator 和 ItalicDecorator 是具体的装饰器类。通过装饰器,我们可以在不改变原始文本对象的情况下,动态地为文本添加样式。