转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> JAVA开发 >> 正文
Java中Decorate的三种实现方法         ★★★★

Java中Decorate的三种实现方法

作者:闵涛 文章来源:闵涛的学习笔记 点击数:807 更新时间:2009/4/22 23:28:22
1b01 天极IT资讯短信服务 电脑小技巧
资费:包月5元
手机
介绍:细处着手,巧处用功。高手和菜鸟之间的差别就是:高手什么都知道,菜鸟知道一些。电脑小技巧收集最新奇招高招,让你轻松踏上高手之路。
  每一位读过GoF的那本著名的设计模式一书的人都会知道Decorator模式。现在,让我们暂时忘记所了解的Decorator概念,尝试着从我们的开发经验中去理解Decorator模式吧。

  Decorator是用于装饰一个事物(或人)的另一个事物(或人)。一个Decorator直接改变被装饰对象的职责或特征,但是不能改变被装饰对象的自有属性。例如:一个镜框可以装饰图片,化妆品可以装饰女孩的脸等等。

  从我们的专业角度来讨论一些存在的实例:

  1 JScrollPane可以装饰JComponent的视图部分。JComponent本身并不会被改变,但是增加了一个新的属性(可滚动)。

  2 BufferedInputStream是InputStream的装饰子,本身BufferedInputStream就是一个InputStream,但是它更快,因为提供了对数据的缓存。

  3 考虑一下DebugButton,它与JButton一样,但是它在被点击时可以向日志文件添加消息。DebugButton是JButton的装饰子,因为它直接改变了JButton但并没有改变它的自有属性。

  4 再又如ScrollOverButton,它增加了一个鼠标滑过的行为。当鼠标移出时它是平的,当鼠标经过时它具有一个凸起的边框。很显然,ScrollOverButton也是JButton的装饰子。

  现在,我们知道Decorator可能有三种不同的实现:

  1 继承(Inheritance)
  2 封装(Wrapper)
  3 外挂(External)

  本文将讨论每一个实现模型,以及它们的优缺点。

  继承

  对于开发人员而言,最直观的Decorator实现就是:写一个派生类,它继承自被装饰类,并赋于新的职责。新的职责可以是通过增加方法或是修改已有方法来实现。

public class DebugButton extends JButton
{
public DebugButton()
{
addActionListener(new ActionListener()
{
System.out.println("debug message");
});
}
}
  此外,我们也可以用相同的方式来实现ScrollOverButton:不是增加ActionListener,而是增加MouseListener。在MouseListener回调方法中改变JButton的边框,当mouseEntered()被调用时,将边框从EmpetyBorder变为RaisedBevelBorder。而当mouseExited()方法被调用时,再将边框从RaisedBevelBorder恢复成EmpetyBorder。

  对于BufferedInputStream,同样实现也是非常简单的。修改每个读数据的方法,让它从内存缓冲区来读取数据。如果缓冲区是空的,它可以通过super.read()方法来获取数据并填充缓冲区。JScrollPane,要实现起来就有点复杂,下面我将讨论为什么它会比较难以用继承的方式来实现。

  讨论一下继承方式实现Decorator模式的优点与缺点:

  优点

  1 我们几乎可以用这个方式实现所有的Decorator。

  2 使用继承方式实现Decorator模式,可以保留被装饰类的原始类型,这一点是非常重要的。用继承方式,我们仍可以使用被装饰类的在被装饰之前的类型,例如,我们可以在我们的应用程序中使用crollOverButton代替JButton,但是JScrollPane就不能代替包含在它内部的对象。

  缺点

  1 用继承的方式仍不够直接。设想一下我们实现了ScrollOverButton和DebugButton,但是我们又需要实现一个既有ScrollOverButton特点又有DebugButton行为的按钮。怎么办?用继承方式我们唯一的选择就是再派生出一个ScrollOverDebugButton类。如果我们有了ScrollOverDebugButton的实现,那么是否还需要继续保留ScrollOverButton或DebugButton实现?因为我们可以为ScrollOverDebugButton增加两对方法来打开或关闭debug或scroll-over的行为:

public void setDebug(boolean b);
public boolean isDebug();

public void setScrollOver(boolean b);
public boolean isScrollOver();
  再进一步考虑,如果将来我们有更多的装饰功能,增加新的U1,U2,......Un个行为。我们是不是要写一个类,叫U1U2...UnButton?它是不是要包括2n个这样的方法:

public void setU(boolean b);
public boolean getU;();
  每增加一个新的行为(Un+1)给装饰器就需要增加两个新的方法,并要修改这个装饰器的代码实现。这明显与面向对象的思想相悖,可能会产生严重的后果。(注意:javax.swing.JButton就是这样实现的)。

  2 多数可视化对象的行为是由风格参数来指定的,而风格的改变是不可预知的。当风格发生了改变,我们不得不调整自己的改变。正如上面所述,使用继承的方式可能需要改变实现的代码。

  3 要保证被装饰类的原始类型也不是一件容易的事。我们需要重载每个构造子,有时甚至是静态方式。尽管这不困难,但总是相当麻烦的一件事。

  用继承方式来实现Decorator模式并不象我们先前想像的那么简单。许多时候,我们并不知道将来我们需要哪一些装饰器,结果是,使用继承方式的Decorator在扩展性方面相当困难,并且与面向对象的原则会产生冲突。
  
157


没有相关教程
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台