动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
电脑书籍下载:程序设计书籍 | 数据库教程书籍 | 平面与多媒体书籍 | 网络通讯书籍 | 系统管理书籍 | 网络安全书籍 | 认证考试书籍
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > Java教程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ Java教程 ]的信息



本月文章推荐
.面向方面编程AOP和JBoss(一).
.Designing “query by criteria”.
.java开源项目研究.
.EJB3.0学习之运行环境配置.
.在Java中如何实现长时间任务.
.乘法赋值运算符 (*=).
.java设计模式之ChainofResponsib.
.EJB的编程限制.
.在UML中表示Java继承和接口.
.基于Struts的权限实现.
.简单介绍Java语言中内存管理的几.
.Java编程实践应用:J2EE架构的6个.
.父类和子类转换(子类对象赋值给父.
.获取运行中的JVM系统属性.
.Java Applet基础入门之数据类型.
.java api之实现(下).
.从Hibernate2到3移植的两点初体验.
.安全技术 Java与安全性,第2部分.
.应用Rational 工具简化基于J2EE的.
.应用Rational 工具简化基于J2EE的.

Java中Decorate的三种实现方法

发表日期:2008-1-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在扩展性方面相当困难,并且与面向对象的原则会产生冲突。
  封装(Wrapper)

  封装实现最主要的思想是将被装饰的对象封装入Decorator模式中。Decorator将外界请求转发给封装的被装饰对象,并且在转发之前(或之后)执行自己新增的功能,或者也可以提供新的独立方法来实现新增功能。

  让我们回到刚才的例子并且重新把它们用封装方式来实现:

  1 BufferedInputStream是一个InputStream的封装,(关于这一点可以参考JDK中java.io.BufferedInputStream类的说明或源码)。尽管事实上BufferedInputStream也是InputStream的一个派生类。作为封装,在BufferedInputStream的构造子中获取了另一个InputStream对象,并且将它作为实例变量保存起来,然后它可以转发请求到这个内置的InputStream对象中。我们可以使用BufferedInputStream在我们原来使用InputStream场合。

  2 JScrollPane也是一个封装的实现。它转发请求到被封装的组件中(它们被称之为视图)。要注重的是,我们不能够使用JScrollPane代替它内部的组件,因为它不支持所有的视图功能。例如,在JScrollPane的getFont()返回的是JScrollPane的字体而不是视图的字体。

  3 我们可以用这种方式实现DebugButton:


上一篇:面向对象编程:Java复杂数据类型用法 人气:328
下一篇:Java线程控制的图像分割与合成 人气:341
浏览全部Java的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-7-24 Sablog-X v2.0 预览版
2008-7-24 帝国备份王EmpireBak 2008 正式版
2008-7-24 网趣网上购物系统时尚版 v8.2
2008-7-24 纵横B2B电子商务系统XYECS!B2B v
2008-7-24 e路小说小偷 v1.2.0723
2008-7-24 凌风美女图片站程序 v2.2
2008-7-24 TOM15电影收索程序
2008-7-24 清风信息自动采集生成系统 v1.0
2008-7-24 QQ邮箱编辑器 v1.0 (小小菜刀ASP
2008-7-19 UltraEdit 简体中文增强版 14.10
2008-7-19 CentOS 5.2 i386 LiveCD
2008-7-19 Snapture多功能相机 v1.4
2008-7-19 iAcces中文输入法 v1.0Build016
2008-7-19 Cookbook烹饪秘籍 v2.5
2008-7-19 苹果专用DVD转换工具 v1.1.59汉化
2008-7-19 Modem修复软件ZiPhone修改版04.0
2008-7-19 AgileMessenger即时通讯工具美化
2008-7-19 Sketches画图软件 v0.7b6破解版


  发表评论
姓 名: 验证码:
内 容:
[ 汉字翻译拼音 ] [ 广告代码 ] [ 符号对照表 ] [ 进制转换 ] [ 经典小工具 ] [ 个税计算 ] [ 汉字简繁转换 ] [ 普通单位换算 ] [ 公制单位换算 ]
[ 生辰老黄历 ] [ 国内电话区号 ] [ 国家代码与域名缩写 ] [ 文字加密解密 ] [ 健康查询 ] [ 万年历 ] [ 手机号码查询 ] [ ip搜索 ] [ Google PR查询 ]
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号
ホームページ制作 不動産検索システム 求人情報
防水工事·改修工事 フットサル大会 探偵