知识大全 Disneytiger

Posted

篇首语:知识的领域是无限的,我们的学习也是无限期的。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Disneytiger相关的知识,希望对你有一定的参考价值。

使用Decorator模式 翻译者:Disneytiger  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

   使用Decorator模式  Java程序员知道可以通过扩展一个类来改变类的行为和扩展一个类的功能 这个行为被称为继承 它是面向对象编程的一个重要的特性   举例来说 如果你想得到一个带有边框的Swing类型标签 你可以子类化javax swing JLabel类 然而 子类化并不总是有效 当继承不能解决问题的时候 你不得不求助与其它的方式 比如 使用Decorator模式   这篇文章解释了Decorator模式是什么 并说明什么时候应该子类化 什么时候应该采用Decorate模式   在Java语言中关键字extends被提供来子类化(扩展)一个类 具有丰富的面向对象编程经验的程序员知道子类化的威力 通过扩展一个类 我们能够改变这个类的行为 以列表 所讲的JBorderLabel类为例 它扩展了javax swing JLabel类 除了多了一个边框 它和JLabel类具有相同的外观和行为   the JBorderLabel class an example of subclassing  package decorator;    import java awt Graphics;  import javax swing JLabel;  import javax swing Icon;    public class JBorderLabel extends JLabel     public JBorderLabel()   super();      public JBorderLabel(String text)   super(text);      public JBorderLabel(Icon image)   super(image);      public JBorderLabel(String text Icon image int horizontalAlignment)   super(text image horizontalAlignment);      public JBorderLabel(String text int horizontalAlignment)   super(text horizontalAlignment);      protected void paintComponent(Graphics g)   super paintComponent(g);  int height = this getHeight();  int width = this getWidth();  g drawRect( width height );      要理解JBorderLabel如何工作 我们首先要了解Swing绘它的组件的原理 JLabel类同其它的Swing组件一样 继承至javax swing Jponent Swing 它们都是通过调用JComponent组件的paint方法来画界面 我们可以通过重载JComponent的公开方法paint来修改一个组件画界面的行为 下面是一个JComponent的paint方法的定义   public void paint(Graphics g)  作为paint方法的参数传进来的对象Graphics是一个绘图面板 为了优化绘图这个操作 paint方法被分割成三个具有保护(protected)属性的方法 paintComponent paintBorder paintChildren paint方法调用这三个方法同时将它接受到的Graphics实例传递给这三个方法 下面是这三个函数的一个声明   protected void paintComponent(Graphics g)  protected void paintBorder(Graphics g)  protected void paintChildren(Graphics g)  你可以通过重载这些方法来定制你自己的绘制组件的方式   JBorderLabel类重载了javax swing JComponent的paintComponent方法 类JborderLabel的paintComponent方法首先调用父类的paintComponent得到一个Jlabel 它保持了自己的长和宽 通过java awt Graphics实例的drawRect方法画一个矩形 图 显示了一个JBorderLabel类的一个实例 正如图所示的一样 出了多了一个边框外 它和JLabel外观是一样的   这个例子中子类化工作得相当好 我们来看看子类化不合适的案例 如果你打算让其它的组件都具有同一行为(比如 画一个边框) 那么你必须做很多的子类化操作 在列表 中 子类化看起来很简单是因为例子中你仅仅需要重载一个方法 当你有太多的子类需要创建时你的代码将变得很复杂 出错的机会也增大了 (你必需要复制(reproduce)你的子类需要支持的父类的构造函数 就像JBorderLabel类一样) 在这个时候 最好的方式是使用Decorator模式      Decorator模式  在Erich Gamma等编写的《Design Patterns : Elements of Reusable Object Oriented Sofare》一书中 Decorator模式被归类为结构模式 Decorator模式提供了子类化的一个替代方案 子类化和Decorator模式的主要区别是 采用子类化 你同一个类打交道 使用Decorator模式 你可以动态的修改多个对象 当你扩展(Extend)一个类的时候 你对儿子类的改变将会影响到这个儿子类所有的实例 采用Decorator模式 你所作的改变只会影响到你打算改变的那个对象   理解JComponent类对于书写装饰者类很重要 我们通过这个装饰者类来改变Swing组件的用户界面 在前面部分我解释了JComponent是如何画它的用户界面的 我们可以通过文档查找来了解这个类的所有的成员 我们要意识到JComponent有子组件 当JComponent被画的时候 这些子组件也将被画   创建一个从JComponent扩展过来的Swing装饰者 这个装饰者的构造函数接受一个类型为JComponent的参数 可以传递任一一个需要改变行为的Swing对象给装饰者 这个装饰者将传进来的这个组件作为自己的子组件 并不是直接将Swing组件增加到JFrame或JPannel或其它容器 而是先将Swing组件添加到修饰者 再把修饰者增加给容器类 因为一个修饰者也是一个JComponent类型的对象 容器不能将他们区分开来 这个装饰者是这个容器的一个子组件 当容器让装饰者重画的时候 这个装饰者paint方法将被调用   举例来说 假设你有一个JLabel类 你打算把它传给一个称之为frame 的JFrame类 使用如下相似的代码   frame getContentPane() add(new JLabel( a label ));用MyDecorator来修饰JLabel的代码和它很相似 如下 (记住 MyDecorator类的构造函数应该接受一个JComponent类的输入参数)  frame getContentPane() add(new MyDecorator(new JLabel( a label )));  这篇文章示例了两个Decorator模式的例子 第一个例子是BorderDecorator 这个类被用来修饰JComponent 以便让JComponent具有一个边框 当把一个由BorderDecorator修饰的JLabel增加到JFrame 这个JLabel看起来就像JBorderLabel的一个实例 这说明 子类化不是必须的 更好的是 你能够传递任何一个Swing组件给BorderDecorator 这些被传递的组件都会给予一个边框 在这个例子中 通过创建了一个类BorderDecorator来改变不同类型的实例的行为   第二个例子是ResizableDecorator 这个装饰著为每一个传给它的Swing组件增加一个小按钮到左上角 当用户点击这个按钮的时候 这个组件将会最小化为这个按钮      BorderDecorator类  我们以BorderDecorator开始 这个类表示的装饰者会为Swing组件增加一个边框 示例代码如列表   the BorderDecorator class  package decorator;    import javax swing JComponent;  import java awt Graphics;  import java awt Color;  import java awt BorderLayout;    public class BorderDecorator extends JComponent     // decorated ponent  protected JComponent child;    public BorderDecorator(JComponent ponent)   child = ponent;  this setLayout(new BorderLayout());  this add(child);      public void paint(Graphics g)   super paint(g);  int height = this getHeight();  int width = this getWidth();  g drawRect( width height );      注意 这个BorderDecorator扩展了JComponent 它的构造函数接受一个JComponet类型的参数 这个BorderDecorator类有一个类型为JComponent的属性child 它是传进来的Jponent对象的一个引用   构造函数将被修饰的组件赋值给child变量 并且将这个组件作为一个子组件增加给装饰者 注意 我们使用了BorderLayout作为装饰者的布局 这意味着被增加的这个JComponent将占据这个装饰者的整个区域   现在 让我们关注一下paint方法 它首先调用了父类的paint方法 这-步操作将画出装饰者 在第一次得到装饰者的长宽以后 我们在装饰者所在区域的边缘画一个长方形   Figure shows a JFrame with three ponents:  &# ; An instance of JBorderLabel   &# ; A decorated JLabel   &# ; A decorated JCheckBox     Figure paring subclassing and the Decorator pattern  JBorderLabel的一个实例和一个被装饰过的JLabel对象实例从外表看没有什么不同 这说明 Decorator模式可以作为子类化的一个替代方案 第三个组件证明 你能够使用同一个装饰者去扩展不同对象的实例的行为 从这点来看 装饰者是一个(超类)superior 因为仅仅需要创建一个类(BorderDecorator)就可以扩张不同类型的多个对象的功能   显示了图 中的JFrame类的实现代码    using the BorderDecorator class  package decorator;    import java awt *;  import javax swing *;  import java awt event *;    public class Frame extends JFrame     JBorderLabel label =  new JBorderLabel( JLabel Subclass );    BorderDecorator label =  new BorderDecorator(new JLabel( Decorated JLabel ));    BorderDecorator checkBox =  new BorderDecorator(new JCheckBox( Decorated JCheckBox ));    public Frame ()   try   this setDefaultCloseOperation(EXIT_ON_CLOSE);  getContentPan cha138/Article/program/Java/gj/201311/27319

相关参考