如鹏网 大学生计算机学习社区

CowNew开源团队

http://www.cownew.com 邮件请联系 about521 at 163.com

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  363 随笔 :: 2 文章 :: 808 评论 :: 0 Trackbacks

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;

}

关于其他的设计模式的使用我在后续文章会继续介绍,给大家推荐一个网站 http://www.cownew.com ,是个励志类的,不错,看到它的介绍很好,很多文章是从天涯搞下来的。

posted on 2006-03-26 01:46 CowNew开源团队 阅读(950) 评论(1)  编辑  收藏

评论

# re: Decorate(装饰者模式) 实现留言反馈板文本处理 2006-03-27 09:46 luckyrobbie
好方法,谢谢分享  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: