快速业务通道

Java中Decorate的三种实现方法 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-23
,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:

public class DebugButton extends JButton implements ActionListener { private JButton butt = null; public DebugButton(JButton butt) { this.butt=butt; butt.addActionListener(this); } // ActionListener public void actionPerformed(ActionEvent e) { System.out.println("debug message for button" + butt); } . . . . . . . . /* 需要提供约180个类似这样的方法: any JButton method M(params) { butt.M(params) } */

Java中Decorate的三种实现方法(3)

时间:2010-12-08

这保持了被装饰对象的类型(它继承自JButton),但是这仍看上去不是那么直接。

注意:我们不能够使用java.lang.reflect.Proxy来作为代理,因为JButton是一个类而不是一个接口。

另一种实现可以这样:

public class DebugButton extends JComponent implements ActionListener { private JButton butt = null; public DebugButton(JButton butt) { this.butt=butt; butt.addActionListener(this); } public JButton getUnderlineButton() { return butt; } // ActionListener public void actionPerformed(ActionEvent e) { System.out.println("debug message for button" + butt); } . . . . . . . . /* 可以实现一些(不多)可选的方法,象get/setFont,get/setBackground等。 */ }

这个实现方式相当简单,但这样的DebugButton不是从JButton派生出来的,我们不可以用DebugButton代替JButton。JScrollPane就是用这种方式实现的。

4 在Sc

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号