装饰者模式
装饰者模式拥有一个设计非常巧妙的结构,它可以动态的添加对象的功能。在基本的设计原则中,有一条重要的设计原则,叫做 聚合复用 原则。故代码复用应尽可能使用委托,而不是继承。
如果你对此模式没有了解,如是说可能会比较抽象。然而,在JAVA JDK的实现中,不少组件是通过装饰者模式实现的。其中,一个最典型的例子就是OutputStream与InputStream 类族的实现,以OutputStream为例:OutputStream对象提供的方法比较简单,但是通过各种装饰者的增强,OutputStream对象可以被赋予更多强大的功能。
例如以下代码:
package com.zendly.mode.decorator;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class StreamDecorator {
@SuppressWarnings("unused")
public static void main(String[] args) throws FileNotFoundException {
/*带有缓冲功能的输出流对象*/
DataOutputStream dosBuffer =
new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream(new File("D:/decorator.txt"))));
/*没有缓冲功能的输出流对象*/
DataOutputStream dosNoBuffer =
new DataOutputStream(
new FileOutputStream(new File("D:/decorator.txt")));
}
}
以上几行代码中,第一种OutputStream加入了性能组件BufferedOutputStream,第二种则没有,因此,第一个OutputStream对象拥有更好的I/O性能。第一个OutputStream对象,在调用FileOutputStream.write()之前会先调用BufferedOutputStream.write(),查看BufferedOutputStream.write()源代码会发现,并不是每次调用此方法,它都会去磁盘写入数据,而是将数据写入缓存,当缓存满时,才会调用FileOutputStream.write(),实际写入数据。如此,实现了功能组件与性能组件的完美分离。
装饰者模式一个典型的案例就是对输出结果进行增强。比如,现在我们要对某一内容结果通过HTML发布,首先,要将内容转化为HTML文本。同时,还要为内容添加HTTP头。一个简单的实现步骤如下:
a.首先我们构造顶级业务接口IPacketCreator:
package com.zendly.mode.decorator;
/**
* 顶级核心业务接口
* @author zendly
*/
public interface IPacketCreator {
public String dealContent();
}
b.其次,就是我们的主要装饰者对象PacketDecorator:
package com.zendly.mode.decorator;
/**
* PacketDecorator 维护核心组件creator
* 它负责告知子类,核心业务逻辑应该委托IPacketCreator完成
* PacketDecorator本身只作业务功能增强处理
* @author zendly
*/
public abstract class PacketDecorator implements IPacketCreator{
IPacketCreator creator;
public PacketDecorator(IPacketCreator creator) {
this.creator = creator;
}
}
c.然后,是我们的HTML具体装饰者对象PacketHTMLDecorator:
package com.zendly.mode.decorator;
/**
* HTML文本的包装
* @author zendly
*/
public class PacketHTMLDecorator extends PacketDecorator {
public PacketHTMLDecorator(IPacketCreator creator) {
super(creator);
}
@Override
public String dealContent() {
StringBuffer sb = new StringBuffer();
sb.append("<html><body>");
sb.append(creator.dealContent());
sb.append("</body></html>\n");
return sb.toString();
}
}
d.然后,是HTTP头具体装饰者对象PacketHTTPDecorator:
package com.zendly.mode.decorator;
/**
* HTTP头内容的添加
* @author zendly
*/
public class PacketHTTPDecorator extends PacketDecorator{
public PacketHTTPDecorator(IPacketCreator creator) {
super(creator);
}
@Override
public String dealContent() {
StringBuffer sb = new StringBuffer();
sb.append("Connection:keep-alive\n");
sb.append("Accept-Language:zh-CN,zh;q=0.8,en;q=0.6\n");
sb.append("User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64)\n");
sb.append(creator.dealContent());
return sb.toString();
}
}
e.最后,使用这种方法UserDecorator:
package com.zendly.mode.decorator;
public class UserDecorator {
public static void main(String[] args) {
IPacketCreator pc =
new PacketHTTPDecorator(
new PacketHTMLDecorator(
new PacketCoreCreator()));
System.out.println(pc.dealContent());
}
}
分享到:
相关推荐
设计模式--装饰者模式java例子
装饰者模式Demo
装饰者模式 C++ 实现
设计模式 - 装饰者模式
装饰者模式代码demo 装饰者模式代码demo 装饰者模式代码demo
c# ,设计模式,装饰者模式,星巴兹咖啡,基本上就是head first 上的例子的C#实现,根据自己的理解,作了一点点改动,可以直接运行。
装饰者模式的典型应用。 装饰者模式的典型应用。 装饰者模式的典型应用。
Qt设计模式之装饰者模式
设计模式的装饰者模式的例子,希望对大家有用~~~~~~~~
装饰者模式demo
java装饰者模式实现,通过豆浆,加糖加鸡蛋加黑豆生动的实现了装饰着的代码,可以学习,也可以在此基础上进行扩充
装饰者模式学习案例代码 文章:http://blog.csdn.net/hailushijie/article/details/8630106
Head First 设计模式 (三) 装饰者模式(decorator pattern) C++实现 VS2012 下通过
设计模式中的装饰模式,AndroidStudio工程
java设计模式【之】装饰者模式【源码】【场景:煎饼果子+肠+蛋】 * 测试类【之】煎饼果子来一套 * * 不改变原有对象的基础上,强化已经存在的功能 * 被装饰者与装饰者实现同一个抽象或接口 * 装饰后,最终还是...
本章可以称为“给爱用继承的人一个全新的设计眼界”。我们即将再度探讨典型...一旦你熟悉了装饰者的技巧,你将能够在不修改任何底层代码的情况下,给你的(或别人的)对象赋予新的职责。——《Head First 设计模式》
装饰者模式结合模板方法模式实现奶茶商店:原来的奶茶商店需要引进咖啡,用装饰者模式结合模板方法模式
java设计模式之装饰者模式代码