裝飾者模式擁有一種非常巧妙的結(jié)構(gòu),它可以動態(tài)添加對象功能藏研。
它使用委托機制,降低代碼的耦合性背率,復(fù)用系統(tǒng)中的各個組件卒落,使得我們最終構(gòu)造的對象具有這些所有功能羡铲。
裝飾者模式可以有效的分離性能組件和功能組件,從而提升模塊的可維護性并增加模塊的復(fù)用性儡毕。
裝飾者(Decorator
)和被裝飾者(ConcreteComponent
)擁有相同的接口Component
也切。
被裝飾者通常是系統(tǒng)的核心組件,完成特定的功能目標(biāo)腰湾。而裝飾者則可以在被裝飾者的方法前后加上特定的前置處理或者后置處理雷恃,
增強被裝飾者功能。
下面舉例說明:
需求:我們需要將一個內(nèi)容以HTML的方式發(fā)布檐盟。
- 需要將內(nèi)容轉(zhuǎn)換成HTML文本
- 增加HTML頭
- 增加HTTP頭
首先褂萧,我們定義一個組件接口,它的主要功能就是對內(nèi)容進(jìn)行處理葵萎。
public interface IPacketCreator {
public String handleContent();
}
PacketCreator
用于返回數(shù)據(jù)包的核心數(shù)據(jù):
public class PacketBodyCreator implements IPacketCreator {
@Override
public String handleContent() {
return "Content of Body";
}
}
PacketDecorator
對組件進(jìn)行維護导犹, 它并不實現(xiàn)業(yè)務(wù)邏輯唱凯,僅僅給子類提供一個委托對象。
public abstract class PacketDecorator implements IPacketCreator {
IPacketCreator component;
public PacketDecorator(IPacketCreator creator) {
this.component = creator;
}
}
下面是具體組件的實現(xiàn):
public class PacketHtmlHeaderCreator extends PacketDecorator {
public PacketHtmlHeaderCreator(IPacketCreator creator) {
super(creator);
}
@Override
public String handleContent() {
StringBuilder sb = new StringBuilder();
sb.append("<html>");
sb.append("<body>");
sb.append(component.handleContent());
sb.append("</body>");
sb.append("</html>");
return sb.toString();
}
}
public class PacketHTTPHeaderCreator extends PacketDecorator{
public PacketHTTPHeaderCreator(IPacketCreator creator) {
super(creator);
}
@Override
public String handleContent() {
StringBuffer sb = new StringBuffer();
sb.append("CacheControl:no-cache\n");
sb.append("Date:Sun,21June201515:58:57GMT\n");
sb.append(component.handleContent());
return sb.toString();
}
}
測試:
public class DecoratorTester {
public static void main(String[] args) {
IPacketCreator pc = new PacketHTTPHeaderCreator(
new PacketHtmlHeaderCreator(new PacketBodyCreator()));
System.out.println(pc.handleContent());
}
}
從例子中我們可以看出谎痢,組件的各種功能最后被一層層的嵌入最終的pc中磕昼。
其實裝飾者模式在日常使用中也很常見,比如JDK中的IO Stream
:
DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("/data/file.txt")));
于2015-06-21