装饰器(Decorator)模式,是一种在运行期动态给某个对象的实例增加功能的方法。
1.图示:
Decorator:抽象类,实现Apple接口。
ConcreteDecoratorA、ConcreteDecoratorB:继承Decorator类。
2.示例代码
假设我们需要渲染一个HTML的文本,但是文本还可以附加一些效果,比如加粗、变斜体、加下划线等。为了实现动态附加效果,可以采用Decorator模式。
首先,仍然需要定义顶层接口TextNode:
public interface TextNode {
// 设置text:
void setText(String text);
// 获取text:
String getText();
}
核心节点,例如<span></span>
,它需要从TextNode直接继承:
public class SpanNode implements TextNode {
private String text;
public void setText(String text) {
this.text = text;
}
public String getText() {
return "<span>" + text + "</span>";
}
}
抽象的Decorator类:
public abstract class NodeDecorator implements TextNode {
protected final TextNode target;
protected NodeDecorator(TextNode target) {
this.target = target;
}
public void setText(String text) {
this.target.setText(text);
}
}
这个NodeDecorator类的核心是持有一个TextNode,即将要把功能附加到的TextNode实例。接下来就可以写一个加粗功能:
public class BoldDecorator extends NodeDecorator {
public BoldDecorator(TextNode target) {
super(target);
}
public String getText() {
return "<b>" + target.getText() + "</b>";
}
}
类似的,可以继续加ItalicDecorator、UnderlineDecorator等。客户端可以自由组合这些Decorator;
调用:
TextNode n1 = new SpanNode();
TextNode n2 = new BoldDecorator(new UnderlineDecorator(new SpanNode()));
TextNode n3 = new ItalicDecorator(new BoldDecorator(new SpanNode()));
n1.setText("Hello");
n2.setText("Decorated");
n3.setText("World");
System.out.println(n1.getText());
//输出<span>Hello</span>
System.out.println(n2.getText());
//输出<b><u><span>Decorated</span></u></b>
System.out.println(n3.getText());
//输出<i><b><span>World</span></b></i>
3.应用
IO中
-
InputStream顶层接口。
-
FileInputStream、ServletInputStream实际的子类:
-
FilterInputStream:装饰器抽象类
-
装饰器实现:BufferedInputStream、HttpInputStream、GZIPInputStream等。