中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > Java > 设计模式
Decorate your Java code (1) --A look at the Decorator&…
作者:未知 时间:2005-07-24 21:23 出处:JR 责编:chinaitpower
              摘要:Decorate your Java code (1) --A look at the Decorator design pattern
Author: David Geary 
From: JavaWorld.com
December 14, 2001

Summary


The Decorator design pattern lets you attach responsibilities to objects at runtime. This pattern proves more flexible than inheritance, which is static. In this latest installment of Java Design Patterns, David Geary explores Decorator with an implementation example. (2,800 words; December 14, 2001) 

Being somewhat of a closet Luddite, I only recently purchased my first cell phone. My phone is faceplate-ready -- in other words, I can snap on a stylish faceplate. As far as I can tell, faceplates are the only dynamically changeable aspect of my cell phone. For example, I cannot snap on antennas or speakers; those are set statically at the factory. 

Software decorators, like cell phone faceplates, encapsulate some functionality that you can snap onto an existing object; for example, here's a code fragment that snaps sorting onto an existing Swing table model: 

  1. TableSortDecorator sortDecorator = new TableSortDecorator(table.getModel());
  2. table.setModel(sortDecorator);


The preceding code swaps out a table's model for a decorator. After the swap, whenever the table accesses its model, it unknowingly accesses the sort decorator. The decorator adds sorting capabilities to the model it decorates, and delegates other functionality to the real model. 

Like cell phones, software heavily reliant on inheritance includes a high percentage of statically defined objects. Just as a cell phone's antenna or speaker is statically defined at the factory, base classes and their extensions are statically defined at compile time. Because inheritance is static, it does not allow you to swap out an aspect of an object's behavior at runtime (such as the table model decorator in the code fragment above). Because you can use decorators much like Legos to snap together an object with desired behaviors at runtime, the Decorator design pattern proves far more flexible than inheritance. 

In this article, I first introduce the Decorator pattern, starting with an example that shows how to use Java's I/O decorators. I then outline the Decorator pattern's statics and dynamics with UML class and sequence diagrams, respectively. I conclude with an example decorator that, as alluded to above, adds sorting to Swing tables. 

Note: In the first installment of this column -- "Amaze Your Developer Friends with Design Patterns" -- I introduced Decorator, among other patterns. You may wish to read that introduction before proceeding with this more detailed look. 

The Decorator pattern demystified

 
Decorator: Attaches responsibilities to objects at runtime. Decorators prove more flexible than inheritance, which attaches responsibilities to classes at compile time. 

In "Amaze Your Developer Friends with Design Patterns," I described input streams and the Decorator pattern. Example 1 from that article demonstrates instantiating a line number reader: 

Example 1. Instantiating I/O decorators
 

  1. 1. FileReader       frdr = new FileReader(filename);
  2. 2. LineNumberReader lrdr = new LineNumberReader(frdr);



The preceding code creates a reader -- lrdr -- that reads from a file and tracks line numbers. Line 1 creates a file reader (frdr), and line 2 adds line-number tracking. 

At runtime, decorators forward method calls to the objects they decorate. For example, in the code above, the line number reader, lrdr, forwards method calls to the file reader, frdr. Decorators add functionality either before or after forwarding to the object they decorate; for example, our line number reader tracks the current line number as it reads from an input stream. 

Alternatively, of course, you could write Example 1 like this: 

  1. LineNumberReader lrdr = new LineNumberReader(new FileReader(filename));

Both methods outlined above adhere to the same construction idiom: wrapping objects recursively -- a hallmark of the Decorator design pattern. 

The code in Example 2 below shows how to instantiate and use a line number reader. The example reads lines of text from a file and prints each line with its line number: 

Example 2. Using I/O decorators 


  1. try {
  2.    LineNumberReader lrdr = new LineNumberReader(new FileReader(filename));
  3.    for(String line; (line = lrdr.readLine()) != null;)rticle.txt {
  4.       System.out.print(lrdr.getLineNumber() + ":\t" + line);
  5.    }
  6. }
  7. catch(java.io.FileNotFoundException fnfx) {
  8.    fnfx.printStackTrace();
  9. }
  10. catch(java.io.IOException iox) {
  11.    iox.printStackTrace();


Decorators represent a powerful alternative to inheritance. Whereas inheritance lets you add functionality to classes at compile time, decorators let you add functionality to objects at runtime. 

Decorator statics and dynamics

 
Mechanical engineers study statics and dynamics. Statics analyze forces on objects that don't move very much -- bridges or buildings, for instance. Dynamics analyze forces on moving objects, typically in machines. The centrifugal forces on jet engine blades or clock pendulums are good examples. 

Statics and dynamics have direct counterparts in the realm of software design patterns. Design pattern statics analyze class relationships specified at compile time, whereas design pattern dynamics analyze the runtime sequence of events in which objects participate. In this section, I show design pattern statics with UML class diagrams and design pattern dynamics with UML sequence diagrams. 

Throughout the Java Design Pattern column, I will discuss the static and dynamic aspects of each design pattern we explore. Let's begin by examining the statics and dynamics of the pattern at hand -- Decorator. 

Decorator statics
 
Decorators decorate an object by enhancing (or in some cases restricting) its functionality. Those objects are referred to as decorated. Figure 1 shows the static relationship between decorators and the decorated. 

[i]Figure 1. Decorator class diagram. Click on thumbnail to view full-size image[/i]

Decorators extend the decorated class (or implement the decorated interface), which lets decorators masquerade as the objects they decorate. They also maintain a reference to a Decorated instance. That instance is the object that the decorator decorates. As an example of how the classes in the Decorator pattern relate, Figure 2 depicts the static relationships among four decorators from the java.io package: 
  • BufferedReader

  • LineNumberReader

  • FilterReader

  • PushbackReader


[i]Figure 2. I/O decorators [/i]

BufferedReader and FilterReader are decorators just like the one shown in Figure 1. Both classes extend the abstract Reader class, and both forward method calls to an enclosed Reader. Because they extend BufferedReader and FilterReader, respectively, LineNumberReader and PushbackReader are also decorators. 

Decorator dynamics
 
At runtime, decorators forward method calls to the objects they decorate, as shown in Figure 3.

[i]Figure 3. Decorator dynamics. Click on thumbnail to view full-size image.[/i]

Developers often refer to Decorators as wrappers because they wrap method calls to decorated objects. Figure 3 clearly depicts such wrapping. Figure 4 shows the dynamics of the code listed in Example 2. 

[i]Figure 4. I/O decorator dynamics[/i]

Now that we have a high-level understanding of Decorator's statics and dynamics, let's use an example to examine the implementation of the Decorator pattern.

[i]to be continue...[/i]

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有