Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 395|回复: 0

[设计模式学习]Decorate(装饰者模式) 实现留言版词汇处理

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-29 23:59:08 | 显示全部楼层 |阅读模式
    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 LengthContentFilter(BodyContentFilterIntf aFilter)
         {
           bodyContentFilterIntf = aFilter;
         }
       
         public String filtContent(String aContent) throws ContentFilterException {
          String l_Content = aContent;
          If (bodyContentFilterIntf!=null)
           l_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)).
                 l_Content.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
                       bodyCo         bodyContentFilterIntf  =
                   new  SensitiveWordContextFilter(bodyContentFilterIntf);  
       l_Content = bodyContentFilterIntf.filtContent(bodyContext);
           }
           catch (ContentFilterException ex) {
             BBSCommon.showMsgInResponse(response, ex.getMessage());
             return;
       }
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-5 06:05 , Processed in 0.444228 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表