使用Decorate模式实现留言版词汇处理
来源:网络 更新时间:2014-12-2
装饰者模式以对客户端透明的方式动态的为对象增加责任。此模式提供了一个比继承更为灵活的替代方案来扩展对象的功能,避免了继承方法产生的类激增问题,而且更方便更改对象的责任。
我们经常要为某一些个别的对象增加一些新的职责,并不是全部的类。例如我们系统留言反馈板块中可能需要过滤用户输入留言中的一些词汇(例如政治敏感词汇、色情词汇等)、还可能对用户输入留言进行一些修饰(例如对用户输入的URL自动加上超链接、对用户输入的UBB代码进行转换的)、还可能将用户输入的内容定时发送的网管的邮箱中等等。如果使用类继承的方式进行设计,我们可能要设计一个接口
BodyContentFilterIntf,然后在由BodyContentFilterIntf派生出SensitiveWordContentFilter、HtmlContentFilter、SendEmailContentFilter等类。但是如果还要要求同时能过滤敏感词汇并能进行修饰、或者过滤敏感词汇之后把用户输入的留言发送到网管邮箱等等,这样就要增加SensitiveWordHtmlContentFilter、SensitiveWordSendEmaillContentFilter等类,这种方式导致了子类瀑发式的产生。
一个灵活的方法是将过滤器嵌入另一个过滤器中,由这个过滤器来负责调用被嵌入过滤器的方法并执行自己的过滤器方法。我们称这个嵌入的过滤器为装饰(Decorator)。这个装饰与过滤器接口一致。装饰将请求向前转到到另一个过滤器,并且可能能转发前后执行一些额外的动作(如修饰、发送邮件),透明性使你可以递归的嵌套多个装饰,从面可以添加任意多的功能。
其实Java中的过滤器模式应用非常多,典型的就是IO的Stream操作。在IO处理中,Java将数据抽象为流(Stream)。在IO库中,最基本的是InputStream和OutputStream两个分别处理输出和输入的对象,但是在InputStream和OutputStream中之提供了最简单的流处理方法,只能读入/写出字符,没有缓冲处理,无法处理文件,等等。
LineNumberInputStream、BufferInputStream、StringBufferInputStream等提供各种不同服务的类只要组合起来就可以实现很多功能,如下:
FilterInputStreammyStream=newLineNumberInputStream
(newBufferInputStream(newStringBufferInputStream(myStringBuffer)));
多个的Decorator被层叠在一起,最后得到一个功能强大的流。既能够被缓冲,又能够得到行数,这就是Decorator的威力!
下面是我们的类静态图
我们定义一个接口BodyContentFilterIntf来定义所有过滤器要实现的方法:
publicinterfaceBodyContentFilterIntf{
publicStringfiltContent(StringaContent)throwsContentFilterException;
}
这个接口中只有一个方法filtContent,将要过滤的留言传给aContent参数,filtContent对aContent进行一些处理(如装饰URL、UBB等),然后将处理后的字符串做为返回值返回;如果留言没有通过过滤(如含有敏感词汇等),只要抛出自定义ContentFilterException异常即可。
下面是一个可能的一个过滤器(保证输入的字数多于50):
publicclassLengthContentFilter
implementsBodyContentFilterIntf{
privateBodyContentFilterIntfbodyContentFilterIntf=null;
publicHtmlContentFilter(BodyContentFilterIntfaFilter)
{
bodyContentFilterIntf=aFilter;
}
publicStringfiltContent(StringaContent)throwsContentFilterException{
Stringl_Content=aContent;
If(bodyContentFilterIntf!=null)
_Content=bodyContentFilterIntf.filtContent(l_Content);
if(aContent.length()<=50)