使用Decorate模式实现留言版词汇处理

  装饰者模式以对客户端透明的方式动态的为对象增加责任。此模式提供了一个比继承更为灵活的替代方案来扩展对象的功能,避免了继承方法产生的类激增问题,而且更方便更改对象的责任。

  我们经常要为某一些个别的对象增加一些新的职责,并不是全部的类。例如我们系统留言反馈板块中可能需要过滤用户输入留言中的一些词汇(例如政治敏感词汇、色情词汇等)、还可能对用户输入留言进行一些修饰(例如对用户输入的URL自动加上超链接、对用户输入的UBB代码进行转换的)、还可能将用户输入的内容定时发送的网管的邮箱中等等。如果使用类继承的方式进行设计,我们可能要设计一个接口

  BodyContentFilterIntf,然后在由BodyContentFilterIntf派生出SensitiveWordContentFilter、HtmlContentFilter、SendEmailContentFilter等类。但是如果还要要求同时能过滤敏感词汇并能进行修饰、或者过滤敏感词汇之后把用户输入的留言发送到网管邮箱等等,这样就要增加SensitiveWordHtmlContentFilter、SensitiveWordSendEmaillContentFilter等类,这种方式导致了子类瀑发式的产生。

  一个灵活的方法是将过滤器嵌入另一个过滤器中,由这个过滤器来负责调用被嵌入过滤器的方法并执行自己的过滤器方法。我们称这个嵌入的过滤器为装饰(Decorator)。这个装饰与过滤器接口一致。装饰将请求向前转到到另一个过滤器,并且可能能转发前后执行一些额外的动作(如修饰、发送邮件),透明性使你可以递归的嵌套多个装饰,从面可以添加任意多的功能。

  其实java中的过滤器模式应用非常多,典型的就是IO的Stream操作。在IO处理中,Java将数据抽象为流(Stream)。在IO库中,最基本的是InputStream和OutputStream两个分别处理输出和输入的对象,但是在InputStream和OutputStream中之提供了最简单的流处理方法,只能读入/写出字符,没有缓冲处理,无法处理文件,等等。

  LineNumberInputStream、BufferInputStream、StringBufferInputStream等提供各种不同服务的类只要组合起来就可以实现很多功能,如下:

FilterInputStream myStream=new LineNumberInputStream
( new BufferInputStream( new StringBufferInputStream( myStringBuffer)));
  多个的Decorator被层叠在一起,最后得到一个功能强大的流。既能够被缓冲,又能够得到行数,这就是Decorator的威力!

  下面是我们的类静态图

  我们定义一个接口BodyContentFilterIntf 来定义所有过滤器要实现的方法:

public interface BodyContentFilterIntf {
 public String filtContent(String aContent) throws ContentFilterException;
}
  这个接口中只有一个方法filtContent,将要过滤的留言传给aContent参数,filtContent对aContent进行一些处理(如装饰URL、UBB等),然后将处理后的字符串做为返回值返回;如果留言没有通过过滤(如含有敏感词汇等),只要抛出自定义ContentFilterException异常即可。

  下面是一个可能的一个过滤器(保证输入的字数多于50):

public class LengthContentFilter

implements BodyContentFilterIntf {
 private BodyContentFilterIntf bodyContentFilterIntf = null;
 public HtmlContentFilter(BodyContentFilterIntf aFilter)
 {
  bodyContentFilterIntf = aFilter;
 }

 public String filtContent(String aContent) throws ContentFilterException {
  String l_Content = aContent;
  If (bodyContentFilterIntf!=null)
   _Content = bodyContentFilterIntf .filtContent(l_Content);
  if (aContent.length()<=50)
   throw new ContentFilterException (“输入的字数不能少于50!”);
    return aContext;
 }
}
  这是另一个过滤器(伪码,用来实现向网管邮箱发送邮件) public class SendEmailContentFilter

implements BodyContentFilterIntf {
 private BodyContentFilterIntf bodyContentFilterIntf = null;
 public SendEmailContentFilter(BodyContentFilterIntf aFilter)
 {
  bodyContentFilterIntf = aFilter;
 }

 public String filtContent(String aContent) throws ContentFilterException {
  String l_Content = aContent;
  if (bodyContentFilterIntf!=null)
   l_Content = bodyContentFilterIntf .filtContent(l_Content);
   SendEmail(“webmaster@SnailWeb.com”,l_Content)
  return aContext;
 }
}
  当然还有SensitiveWordContextFilter(过滤敏感词汇),HtmlContentFilter(修饰用户输入留言中的超级链接)等。

  有了这些过滤器,我们就可以很方便的为留言版添加各种复合的过滤器。例如我们想对输入的留言进行超链接修饰和过滤敏感词汇,那么我们只要如下调用即可:

try {
 l_Content = new HtmlContentFilter(new SensitiveWordContextFilter(null)).
 filtContent(bodyContext);
}

catch (ContentFilterException ex) {
 BBSCommon.showMsgInResponse(response, ex.getMessage());
 return;
}
  我们甚至可以动态的添加不同的过滤器,例如对于会员我们要对输入的留言进行超链接修饰并且将他的留言发送到网管邮箱,而对于非会员我们则要过滤他输入的敏感词汇并且保证输入的字数不少于50,我们只要如下调用即可:

try {
 BodyContentFilterIntf bodyContentFilterIntf = null;
 bodyContentFilterIntf = new HtmlContentFilter(null);
 if(IsMember==true)
  bodyContentFilterIntf = new sendEmailContentFilter(bodyContentFilterIntf);
 else
  bodyContentFilterIntf = new SensitiveWordContextFilter(bodyContentFilterIntf);
 l_Content = bodyContentFilterIntf.filtContent(bodyContext);
}
catch (ContentFilterException ex) {
 BBSCommon.showMsgInResponse(response, ex.getMessage());
 return;
}

时间: 2024-09-11 00:25:28

使用Decorate模式实现留言版词汇处理的相关文章

Groovy探索 自定义Range 二 自定义Range类与Decorate模式

Decorate模式相信大家都比较熟悉了,是一个"BangOfFour"中最常用的模式之一,实现起来也相当的简单.如果有人不熟悉的话,可以看看<Groovy探索之Decorate模式>,那里面有一个本篇要沿用的例子. 这个例子就是咖啡馆里买咖啡的经典例子,咖啡有原味咖啡,还有根据顾客口味不同进行各种添加,比如加冰.加奶和加糖等等.顾客可以选择不加.加一样或加多样,各种加法的咖啡所买的价格也不一样. 这个例子是Decorate模式实现的最经典的例子.我们在这里希望使用自定义R

一个简易需要注册的留言版程序

1.guestbook.php(留言程序) <html> <head> <script language="JavaScript"> <!-- <!--     var hellotext="为了您的最佳浏览效果请您使用IE4.0以上的版本和800*600分辨率"     var thetext=""     var started=false     var step=0     var time

Groovy探索 自定义Range 二 自定义Range类与Decorate模式(下)

顾客可以需要任何种类的咖啡,我们可以根据Range的范围来调节.你可能会说,且慢,如果我只需要咖啡加奶,怎么办? 这就要麻烦一点: def c = new Coffee() def m = new Milk() m.types = ['Coffee','Milk'] (c..m).each{ println it.description() } 麻烦在于我们不能使用"Base"类默认的"types"的值了,需要自定义"types"的值,如: m.

做一个有下拉功能的留言版_php基础

留言版里有太长的留言的话会把页面撑的很长的,大家对那些很长的留言版是不是觉得看的不舒服,每次都要点很多次滚动条. 如果每次一开始只出现标题,点击标题就会在下方出现内容(注意不是弹出窗口),这样的话是不是很不错呢! 接下来我们就看看如何实现: 首先要对各个标题和内容设上ID,这是第一个留言的ID设置,我们把标题的ID设为td1,内容为tdd1,接下去相同. <TR align=left id=td1 onclick=goit(tdd1) onmouseout=noit(td1) onmouseov

一个简易需要注册的留言版程序_php基础

1.guestbook.php(留言程序) <html> <head> <script language="JavaScript"> <!-- <!--     var hellotext="为了您的最佳浏览效果请您使用IE4.0以上的版本和800*600分辨率"     var thetext=""     var started=false     var step=0     var time

学徒硅谷模式的中国版

文/李好 对于实用主义者而言,完美的商业模式也许是这样:有着纯正的硅谷血统:不管能不能赚到钱,至少已经让风投们掏过钱. 商业模式很重要,它无比直观地将一家公司的业务转化为浓缩的商业语言,让投资人明白值不值得投资.美国几乎定义了这个星球所有成功的互联网商业模式,如果借鉴和模仿是不可避免的话,那么问题在于,为什么众多由硅谷创造.在中国曾备受追捧的模式,到最后越做越亏,纷纷裁员?如果硅谷模式+ 中国市场+银子不能推导出"成功"两字,是哪里出了问题? NTA创新传播机构创始人申音如此定义好的模

phpfans留言版用到的install.php_php实例

复制代码 代码如下: <?php   /*********************************************  *  * 程序名: php爱好者留言板  * 演  示: http://www.phpfans.net/guestbook/  *  * 作 者: 我不是鱼  * Email: deng5765@163.com  * 网 址: http://www.phpfans.net  * 博 客:  http://www.phpfans.net/space/?2  * 版本

简单了解设计模式中的装饰者模式及C++版代码实现_C 语言

由遇到的问题引出的装饰模式 在 OO 设计和开发过程,可能会经常遇到以下的情况:我们需要为一个已经定义好的类添加新的职责(操作),通常的情况我们会给定义一个新类继承自定义好的类,这样会带来一个问题(将在本模式的讨论中给出).通过继承的方式解决这样的情况还带来了系统的复杂性,因为继承的深度会变得很深. 而装饰提供了一种给类增加职责的方法,不是通过继承实现的,而是通过组合. 有关这些内容在讨论中进一步阐述.模式选择装饰模式典型的结构图为: 在 结 构 图 中 , ConcreteComponent

空间留言版-a标签如何实现点击出现表单

问题描述 a标签如何实现点击出现表单 想做一个类似QQ空间的留言,回复功能,不希望有跳转,回复是点击才显示回复表单输入 ,这个应该怎么做 解决方案 我理解的啊,点击一个链接,这个链接触发一个function,用js写的,然后在这个js里,用DOM写出一个textarea,注意:要想想怎么提交这些留言给服务器,也就是使用何种参数传递方式: 解决方法: 1.可以接着写一个按钮在下面,这些都是用js写的,你肯定都学过,然后点击提交,通过from表单提交,这是我想的,不见的成功啊,可以试试 生成上面这些