装饰器(Decorator)模式:一种在运行期动态给某个对象的实例增加功能的方法。
Java提供的工具包中,IO相关工具就普遍大量使用了装饰器模式。
举一个艺术字的例子。
定义文本节点接口
public interface TextNode {
void setText(String text);
String getText();
}
定义一个抽象的文本修饰器
public abstract class NodeDecorator implements TextNode {
protected final TextNode target;
protected NodeDecorator(TextNode target) {
this.target = target;
}
@Override
public void setText(String text) {
this.target.setText(text);
}
}
实际修饰器,span标签修饰
public class SpanNode implements TextNode {
private String text;
@Override
public void setText(String text) {
this.text = text;
}
@Override
public String getText() {
return "<span>" + text + "</span>";
}
}
斜体修饰
public class ItalicDecorator extends NodeDecorator {
public ItalicDecorator(TextNode target) {
super(target);
}
@Override
public String getText() {
return "<i>" + target.getText() + "</i>";
}
}
加粗修饰
public class BoldDecorator extends NodeDecorator {
public BoldDecorator(TextNode target) {
super(target);
}
@Override
public String getText() {
return "<b>" + target.getText() + "</b>";
}
}
测试
public class Test {
public static void main(String[] args) throws IOException {
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());
System.out.println(n2.getText());
System.out.println(n3.getText());
}
}
运行结果:
<span>Hello</span>
<b><u><span>Decorated</span></u></b>
<i><b><span>World</span></b></i>
代码库:https://gitee.com/SlienceDemo/java-ee.git
装饰器模式的“饰品”是热拔插的,可以独立增加核心功能,也可以独立增加附加功能,二者互不影响;可以在运行期动态地给核心功能增加任意个附加功能。
下面这个手抓饼的例子还加入了价格变化,能更好的理解装饰器的好处。
手抓饼