﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-VIRGIN FOREST OF JAVA-文章分类-Design Pattern</title><link>http://www.blogjava.net/RR00/category/2707.html</link><description>不要埋头苦干，要学习，学习，再学习。。。。。
&lt;br&gt;
powered  by &lt;font color='orange'&gt;R.Zeus&lt;/font&gt;</description><language>zh-cn</language><lastBuildDate>Thu, 06 Dec 2007 10:31:43 GMT</lastBuildDate><pubDate>Thu, 06 Dec 2007 10:31:43 GMT</pubDate><ttl>60</ttl><item><title>Proxy Pattern</title><link>http://www.blogjava.net/RR00/articles/165774.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Thu, 06 Dec 2007 04:52:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/165774.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/165774.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/165774.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/165774.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/165774.html</trackback:ping><description><![CDATA[http://www.javaworld.com/javaworld/jw-11-2000/jw-1110-proxy.html
<img src ="http://www.blogjava.net/RR00/aggbug/165774.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2007-12-06 12:52 <a href="http://www.blogjava.net/RR00/articles/165774.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Visitor 模式</title><link>http://www.blogjava.net/RR00/articles/96731.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Tue, 30 Jan 2007 06:37:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/96731.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/96731.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/96731.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/96731.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/96731.html</trackback:ping><description><![CDATA[
		<strong>Visitor 模式</strong>
		<br />
		<br />Reference：<br />   1.http://www.javaworld.com/javaworld/javatips/jw-javatip98.html<br />   2.http://www.theserverside.com/patterns/thread.tss?thread_id=43755<br />   3.http://www.nshen.net/designpattern/DesignPattern/VisitorPattern.htm<img src ="http://www.blogjava.net/RR00/aggbug/96731.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2007-01-30 14:37 <a href="http://www.blogjava.net/RR00/articles/96731.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>mappings.setDefaultLazy(dlNode == null || dlNode.getValue().equals("true"));</title><link>http://www.blogjava.net/RR00/articles/73081.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Sat, 30 Sep 2006 10:07:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/73081.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/73081.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/73081.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/73081.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/73081.html</trackback:ping><description><![CDATA[
		<font color="#ff0000">1st:</font>   mappings.setDefaultLazy(dlNode == null || dlNode.getValue().equals("true"));<br /><font color="#ff0000">2ed:</font>  mappings.setAutoImport((aiNode == null) ? true : "true".equals(aiNode.getValue()));<br /><br />the first is seems a bit more effective than the second but less readable ,hence we choose the second!<br />bad programmer write code readed by machine and by contraries good programmer write code readed by human!<img src ="http://www.blogjava.net/RR00/aggbug/73081.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-09-30 18:07 <a href="http://www.blogjava.net/RR00/articles/73081.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>about callback and decorator pattern</title><link>http://www.blogjava.net/RR00/articles/72855.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Fri, 29 Sep 2006 08:17:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/72855.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/72855.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/72855.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/72855.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/72855.html</trackback:ping><description><![CDATA[callback is using when many object has the same pre-init and finally work.<br />decorator is using when one object has may ways to do pre-init and finally work.<img src ="http://www.blogjava.net/RR00/aggbug/72855.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-09-29 16:17 <a href="http://www.blogjava.net/RR00/articles/72855.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>another method equals abstract factory method pattern </title><link>http://www.blogjava.net/RR00/articles/72630.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Thu, 28 Sep 2006 09:20:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/72630.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/72630.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/72630.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/72630.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/72630.html</trackback:ping><description><![CDATA[abstract factory method pattern create an abstract method for uncertain logic application which used in this class's other method so the class can complete  the logic operate. there is another way to do so that is <font style="BACKGROUND-COLOR: #ee82ee">nested public static interface</font> .<br />I found this when i read the org.hibernate.hql.ast.util.NodeTraverser.by the way,the command pattern is somewhat like those way.<img src ="http://www.blogjava.net/RR00/aggbug/72630.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-09-28 17:20 <a href="http://www.blogjava.net/RR00/articles/72630.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java IO 包中的Decorator模式 </title><link>http://www.blogjava.net/RR00/articles/72594.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Thu, 28 Sep 2006 07:34:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/72594.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/72594.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/72594.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/72594.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/72594.html</trackback:ping><description><![CDATA[
		<p>JDK为程序员提供了大量的类库，而为了保持类库的可重用性，可扩展性和灵活性，其中使用到了大量的设计模式，本文将介绍JDK的I/O包中使用到的Decorator模式，并运用此模式，实现一个新的输出流类。 <br /><br /><strong>　　Decorator模式简介 </strong><br /><br />　　Decorator模式又名包装器(Wrapper)，它的主要用途在于给一个对象动态的添加一些额外的职责。与生成子类相比，它更具有灵活性。<br />有时候，我们需要为一个对象而不是整个类添加一些新的功能，比如，给一个文本区添加一个滚动条的功能。我们可以使用继承机制来实现这一功能，但是这种方法不够灵活，我们无法控制文本区加滚动条的方式和时机。而且当文本区需要添加更多的功能时，比如边框等，需要创建新的类，而当需要组合使用这些功能时无疑将会引起类的爆炸。<br /><br />　　我们可以使用一种更为灵活的方法，就是把文本区嵌入到滚动条中。而这个滚动条的类就相当于对文本区的一个<strong>装饰</strong>。这个装饰(滚动条)必须与被装饰的组件(文本区)继承自同一个接口，这样，用户就不必关心装饰的实现，因为这对他们来说是透明的。装饰会将用户的请求转发给相应的组件(即调用相关的方法)，并可能在转发的前后做一些额外的动作(如添加滚动条)。通过这种方法，我们可以根据组合对文本区嵌套不同的装饰，从而添加任意多的功能。这种动态的对对象添加功能的方法不会引起类的爆炸，也具有了更多的灵活性。<br /><br />　　以上的方法就是<strong>Decorator模式</strong>，它通过给对象添加装饰来动态的添加新的功能。如下是Decorator模式的UML图：</p>
		<p align="center">
				<br />
				<img height="288" src="http://cimg.163.com/catchpic/E/EF/EFD7757ECF4A444F276835913426D10D.jpg" width="391" border="0" o&shy;nload="javascript­:resizepic(this)" o&shy;nmousewheel="return bbimg(this)" />
		</p>
		<p>
				<br />　　Component为组件和装饰的公共父类，它定义了子类必须实现的方法。<br /><br />　　ConcreteComponent是一个具体的组件类，可以通过给它添加装饰来增加新的功能。<br /><br />　　Decorator是所有装饰的公共父类，它定义了所有装饰必须实现的方法，同时，它还保存了一个对于Component的引用，以便将用户的请求转发给Component，并可能在转发请求前后执行一些附加的动作。<br /><br />　　ConcreteDecoratorA和ConcreteDecoratorB是具体的装饰，可以使用它们来装饰具体的Component。<br /><br /><strong>　　Java IO包中的Decorator模式</strong><br /><br />　　JDK提供的java.io包中使用了Decorator模式来实现对各种输入输出流的封装。以下将以java.io.OutputStream及其子类为例，讨论一下Decorator模式在IO中的使用。<br /><br />　　首先来看一段用来创建IO流的代码：<br /><br /><font face="新宋体"><code><font style="FONT-WEIGHT: bold; COLOR: #990000">以下是代码片段：</font><br />try { <br />　OutputStream out = new DataOutputStream(new FileOutputStream("test.txt")); <br />} catch (FileNotFoundException e) { <br />　e.printStackTrace(); <br />}</code><br /></font>　　这段代码对于使用过JAVA输入输出流的人来说再熟悉不过了，我们使用DataOutputStream封装了一个FileOutputStream。这是一个典型的Decorator模式的使用，FileOutputStream相当于Component，DataOutputStream就是一个Decorator。将代码改成如下，将会更容易理解：<br /><br /><font face="新宋体"><code><font style="FONT-WEIGHT: bold; COLOR: #990000">以下是代码片段：</font><br />try { <br />　OutputStream out = new FileOutputStream("test.txt"); <br />　out = new DataOutputStream(out); <br />} catch(FileNotFoundException e) { <br />　e.printStatckTrace(); <br />}</code><br /></font>　　由于FileOutputStream和DataOutputStream有公共的父类OutputStream，因此对对象的装饰对于用户来说几乎是透明的。下面就来看看OutputStream及其子类是如何构成Decorator模式的：</p>
		<p align="center">
				<br />
				<img height="225" src="http://cimg.163.com/catchpic/5/5F/5FD3B7C491357BE01991CC6406584520.jpg" width="567" border="0" o&shy;nload="javascript­:resizepic(this)" o&shy;nmousewheel="return bbimg(this)" />
		</p>
		<p>
				<br />OutputStream是一个抽象类，它是所有输出流的公共父类，其源代码如下： <br /><br /><code><font face="新宋体"><font style="FONT-WEIGHT: bold; COLOR: #990000">以下是代码片段：</font><br />public abstract class OutputStream implements Closeable, Flushable { <br />public abstract void write(int b) throws IOException; <br />... <br />}</font></code><br />它定义了write(int b)的抽象方法。这相当于Decorator模式中的Component类。 <br /><br />ByteArrayOutputStream，FileOutputStream 和 PipedOutputStream 三个类都直接从OutputStream继承，以ByteArrayOutputStream为例： <br /><br /><code><font face="新宋体"><font style="FONT-WEIGHT: bold; COLOR: #990000">以下是代码片段：</font><br />public class ByteArrayOutputStream extends OutputStream { <br />protected byte buf[]; <br />protected int count; <br />public ByteArrayOutputStream() { <br />this(32); <br />} <br />public ByteArrayOutputStream(int size) { <br />if (size 〈 0) { <br />throw new IllegalArgumentException("Negative initial size: " + size); <br />} <br />buf = new byte[size]; <br />} <br />public synchronized void write(int b) { <br />int newcount = count + 1; <br />if (newcount 〉 buf.length) { <br />byte newbuf[] = new byte[Math.max(buf.length 〈〈 1, newcount)]; <br />System.arraycopy(buf, 0, newbuf, 0, count); <br />buf = newbuf; <br />} <br />buf[count] = (byte)b; <br />count = newcount; <br />} <br />... <br />}</font></code><br />它实现了OutputStream中的write(int b)方法，因此我们可以用来创建输出流的对象，并完成特定格式的输出。它相当于Decorator模式中的ConcreteComponent类。 <br /><br />接着来看一下FilterOutputStream，代码如下： <br /><br /><code><font face="新宋体"><font style="FONT-WEIGHT: bold; COLOR: #990000">以下是代码片段：</font><br />public class FilterOutputStream extends <u>OutputStream</u> { <br />protected OutputStream out; <br />public FilterOutputStream(OutputStream out) { <br />this.out = out; <br />} <br /></font><font face="新宋体"><strong>public void write(int b) throws IOException { <br />out.write(b); <br />} <br /></strong>... <br />}</font></code><br />同样，它也是从OutputStream继承。但是，它的构造函数很特别，需要传递一个OutputStream的引用给它，并且它将保存对此对象的引用。而如果没有具体的OutputStream对象存在，我们将无法创建FilterOutputStream。由于out既可以是指向FilterOutputStream类型的引用，也可以是指向ByteArrayOutputStream等具体输出流类的引用，因此使用多层嵌套的方式，我们可以为ByteArrayOutputStream添加多种装饰。这个FilterOutputStream类相当于Decorator模式中的Decorator类，它的write(int b)方法只是简单的调用了传入的流的write(int b)方法，而没有做更多的处理，因此它本质上没有对流进行装饰，所以继承它的子类必须覆盖此方法，以达到装饰的目的。 <br /><br />BufferedOutputStream 和 DataOutputStream是FilterOutputStream的两个子类，它们相当于Decorator模式中的ConcreteDecorator，并对传入的输出流做了不同的装饰。以BufferedOutputStream类为例： <br /><br /><code><font face="新宋体"><font style="FONT-WEIGHT: bold; COLOR: #990000">以下是代码片段：</font><br />public class BufferedOutputStream extends FilterOutputStream { <br />... <br />private void flushBuffer() throws IOException { <br />if (count 〉 0) { <br />out.write(buf, 0, count); <br />count = 0; <br />} <br />} <br />public synchronized void write(int b) throws IOException { <br />if (count 〉= buf.length) { <br />flushBuffer(); <br />} <br />buf[count++] = (byte)b; <br />} <br />... <br />}</font></code></p>
		<p>
				<br />　　这个类提供了一个缓存机制，等到缓存的容量达到一定的字节数时才写入输出流。首先它继承了FilterOutputStream，并且覆盖了父类的write(int b)方法，在调用输出流写出数据前都会检查缓存是否已满，如果未满，则不写。这样就实现了对输出流对象动态的添加新功能的目的。<br /><br />　　下面，将使用Decorator模式，为IO写一个新的输出流。</p>
		<p>　　<strong>自己写一个新的输出流</strong><br /><br />　　了解了OutputStream及其子类的结构原理后，我们可以写一个新的输出流，来添加新的功能。这部分中将给出一个新的输出流的例子，它将过滤待输出语句中的空格符号。比如需要输出"java io OutputStream"，则过滤后的输出为"javaioOutputStream"。以下为SkipSpaceOutputStream类的代码：<br /><br /><font face="新宋体"><code><font style="FONT-WEIGHT: bold; COLOR: #990000">以下是代码片段：</font><br />import java.io.FilterOutputStream; <br />import java.io.IOException; <br />import java.io.OutputStream; <br />/** <br />* A new output stream, which will check the space character <br />* and won’t write it to the output stream. <br />* @author Magic <br />* <br />*/ <br />public class SkipSpaceOutputStream extends FilterOutputStream { <br />　public SkipSpaceOutputStream(OutputStream out) { <br />　　super(out); <br />　} <br />　/** <br />　* Rewrite the method in the parent class, and <br />　* skip the space character. <br />　*/ <br />　public void write(int b) throws IOException{ <br />　　if(b!=’ ’){ <br />　　　super.write(b); <br />　　} <br />　} <br />}</code><br /></font>　　它从FilterOutputStream继承，并且重写了它的write(int b)方法。在write(int b)方法中首先对输入字符进行了检查，如果不是空格，则输出。<br /><br />　　以下是一个测试程序：<br /><br /><font face="新宋体"><code><font style="FONT-WEIGHT: bold; COLOR: #990000">以下是代码片段：</font><br />import java.io.BufferedInputStream; <br />import java.io.DataInputStream; <br />import java.io.DataOutputStream; <br />import java.io.IOException; <br />import java.io.InputStream; <br />import java.io.OutputStream; <br />/** <br />* Test the SkipSpaceOutputStream. <br />* @author Magic <br />* <br />*/ <br />public class Test { <br />　public static void main(String[] args){ <br />　　byte[] buffer = new byte[1024]; <br /><br />　　/** <br />　　* Create input stream from the standard input. <br />　　*/ <br />　　InputStream in = new BufferedInputStream(new DataInputStream(System.in)); <br /><br />　　/** <br />　　* write to the standard output. <br />　　*/ <br />　　OutputStream out = new SkipSpaceOutputStream(new DataOutputStream(System.out)); <br /><br />　　try { <br />　　　System.out.println("Please input your words: "); <br />　　　int n = in.read(buffer,0,buffer.length); <br />　　　for(int i=0;i〈n;i++){ <br />　　　　out.write(buffer[i]); <br />　　　} <br />　　} catch (IOException e) { <br />　　　e.printStackTrace(); <br />　　} <br />　} <br />}</code><br /></font>　　执行以上测试程序，将要求用户在console窗口中输入信息，程序将过滤掉信息中的空格，并将最后的结果输出到console窗口。比如：<br /><br /><font face="新宋体"><code bgcolor="#f3f3f3"><font style="FONT-WEIGHT: bold; COLOR: #990000">以下是引用片段：</font><br />Please input your words: <br />a b c d e f <br />abcdef</code><br /></font><strong>　　总 结</strong><br /><br />　　在java.io包中，不仅OutputStream用到了Decorator设计模式，InputStream，Reader，Writer等都用到了此模式。而作为一个灵活的，可扩展的类库，JDK中使用了大量的设计模式，比如在Swing包中的MVC模式，RMI中的Proxy模式等等。对于JDK中模式的研究不仅能加深对于模式的理解，而且还有利于更透彻的了解类库的结构和组成<br /><br />They are the same Obect basically.Decorator is base on the compent but beyond the compent.<br />Delegate is a bit like the Decorator.</p>
<img src ="http://www.blogjava.net/RR00/aggbug/72594.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-09-28 15:34 <a href="http://www.blogjava.net/RR00/articles/72594.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> bridge pattern</title><link>http://www.blogjava.net/RR00/articles/72581.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Thu, 28 Sep 2006 07:02:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/72581.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/72581.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/72581.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/72581.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/72581.html</trackback:ping><description><![CDATA[
		<p>I had understand so far that bridge pattern is just for two interface both has many implementors.articls always instruct following an abstract class that has complex extends and then change the abstract class to bridge class.at the first sight bridge is used to recover the ugly code but in deeply thought ,you may konw that  this pattern is for solveing one situation that two interface both has many implementors work together and use an abstract class as an bridge for the two interface because this pattern is safe to change any one interface and not affect the other,so bridge pattern is so flexible to expand.but if there is more than two interface,how did it do?<br /><br /></p>
		<br />
		<br />
		<br />
		<br />
		<td height="38" width="100%">
		</td>
		<td width="350">
				<br />
				<div>
						<p>
								<strong>Bridge模式定义 </strong>:<br />将抽象和行为划分开来,各自独立,但能动态的结合。</p>
						<p>任何事物对象都有抽象和行为之分，例如人，人是一种抽象，人分男人和女人等；人有行为，行为也有各种具体表现，所以，“人”与“人的行为”两个概念也反映了抽象和行为之分。</p>
						<p>在面向对象设计的基本概念中，对象这个概念实际是由属性和行为两个部分组成的，...</p>
				</div>
		</td>
		<tr>
				<td>
						<br />转载：转载请保留本信息，本文来自<br /><a href="http://www.51dibs.com/info15/i_c_51e22d63fdb3500b.htm">http://www.51dibs.com/info15/i_c_51e22d63fdb3500b.htm</a></td>
		</tr>
		<tr>
				<td width="100%" valign="top">
						<br />
						<table cellspacing="0" cellpadding="0" width="700" align="center" border="0">
								<tbody>
										<tr>
												<td>设计模式之Bridge<br /><div><p><strong>Bridge模式定义 </strong>:<br />将抽象和行为划分开来,各自独立,但能动态的结合。</p><p>任何事物对象都有抽象和行为之分，例如人，人是一种抽象，人分男人和女人等；人有行为，行为也有各种具体表现，所以，“人”与“人的行为”两个概念也反映了抽象和行为之分。</p><p>在面向对象设计的基本概念中，对象这个概念实际是由属性和行为两个部分组成的，属性我们可以认为是一种静止的，是一种抽象，一般情况下，行为是包含在一个对象中，但是，在有的情况下，我们需要将这些行为也进行归类，形成一个总的行为接口，这就是桥模式的用处。</p><p><strong>为什么使用?</strong><br />不希望抽象部分和行为有一种固定的绑定关系，而是应该可以动态联系的。</p><p>如果一个抽象类或接口有多个具体实现(子类、concrete subclass),这些子类之间关系可能有以下两种情况:<br />1. 这多个子类之间概念是并列的,如前面举例,打桩,有两个concrete class:方形桩和圆形桩;这两个形状上的桩是并列的,没有概念上的重复。<br /><br />2.这多个子类之中有内容概念上重叠.那么需要我们把抽象共同部分和行为共同部分各自独立开来,原来是准备放在一个接口里,现在需要设计两个接口：抽象接口和行为接口，分别放置抽象和行为.<br /><br />例如,一杯咖啡为例,子类实现类为四个：中杯加奶、大杯加奶、 中杯不加奶、大杯不加奶。</p><p>但是，我们注意到：上面四个子类中有概念重叠，可从另外一个角度进行考虑，这四个类实际是两个角色的组合：抽象 和行为，其中抽象为：中杯和大杯；行为为：加奶 不加奶（如加橙汁 加苹果汁）. </p><p>实现四个子类在抽象和行为之间发生了固定的绑定关系，如果以后动态增加加葡萄汁的行为，就必须再增加两个类：中杯加葡萄汁和大杯加葡萄汁。显然混乱,扩展性极差。</p><p>那我们从分离抽象和行为的角度，使用Bridge模式来实现。</p><p><strong>如何实现?</strong><br />以上面提到的咖啡 为例. 我们原来打算只设计一个接口(抽象类),使用Bridge模式后,我们需要将抽象和行为分开,加奶和不加奶属于行为,我们将它们抽象成一个专门的行为接口.</p><p>先看看抽象部分的接口代码:<br /></p><table cellspacing="3" cellpadding="3" width="80%" border="0"><tbody><tr><td bgcolor="#cccccc">public abstract class Coffee<br />{<br />　　CoffeeImp coffeeImp;<br /><br />　　public void setCoffeeImp() {<br />　　　　this.CoffeeImp = CoffeeImpSingleton.getTheCoffeImp();<br />　　}<br /><br />　　public CoffeeImp getCoffeeImp() {return this.CoffeeImp;}<br /><br />　　public abstract void pourCoffee();<br />}<br /></td></tr></tbody></table><p>其中CoffeeImp 是加不加奶的行为接口,看其代码如下:</p><table cellspacing="3" cellpadding="3" width="80%" border="0"><tbody><tr><td bgcolor="#cccccc">public abstract class CoffeeImp<br />{<br />　　public abstract void pourCoffeeImp();<br />}<br /></td></tr></tbody></table><p>现在我们有了两个抽象类,下面我们分别对其进行继承,实现concrete class:</p><table cellspacing="3" cellpadding="3" width="80%" border="0"><tbody><tr><td bgcolor="#cccccc"><p>//中杯<br />public class MediumCoffee extends Coffee<br />{<br />　　public MediumCoffee() {setCoffeeImp();}<br /><br />　　public void pourCoffee()<br />　　{<br />　　　　CoffeeImp coffeeImp = this.getCoffeeImp();<br />　　　　//我们以重复次数来说明是冲中杯还是大杯 ,重复2次是中杯<br />　　　　for (int i = 0; i &lt; 2; i++)<br />　　　　{<br /><br />　　　　　　coffeeImp.pourCoffeeImp();<br />　　　　}<br />　　<br />　　}<br />}<br /></p><p>//大杯<br />public class SuperSizeCoffee extends Coffee<br />{<br />　　public SuperSizeCoffee() {setCoffeeImp();}<br /><br />　　public void pourCoffee()<br />　　{<br />　　　　CoffeeImp coffeeImp = this.getCoffeeImp();<br />　　　　//我们以重复次数来说明是冲中杯还是大杯 ,重复5次是大杯<br />　　　　for (int i = 0; i &lt; 5; i++)<br />　　　　{<br /><br />　　　　　　coffeeImp.pourCoffeeImp();<br />　　　　}<br />　　<br />　　}<br />}</p></td></tr></tbody></table><p>上面分别是中杯和大杯的具体实现.下面再对行为CoffeeImp进行继承:</p><table cellspacing="3" cellpadding="3" width="80%" border="0"><tbody><tr><td bgcolor="#cccccc"><p>//加奶<br />public class MilkCoffeeImp extends CoffeeImp<br />{<br />　　MilkCoffeeImp() {}<br /><br />　　public void pourCoffeeImp()<br />　　{<br />　　　　System.out.println("加了美味的牛奶");<br />　　}<br />}<br /></p><p>//不加奶<br />public class FragrantCoffeeImp extends CoffeeImp<br />{<br />　　FragrantCoffeeImp() {}<br /><br />　　public void pourCoffeeImp()<br />　　{<br />　　　　System.out.println("什么也没加,清香");<br />　　}<br />}</p></td></tr></tbody></table><p>Bridge模式的基本框架我们已经搭好了,别忘记定义中还有一句:动态结合,我们现在可以喝到至少四种咖啡:<br />1.中杯加奶<br />2.中杯不加奶<br />3.大杯加奶<br />4.大杯不加奶</p><p>看看是如何动态结合的,在使用之前,我们做个准备工作,设计一个单态类(Singleton)用来hold当前的CoffeeImp:</p><table cellspacing="3" cellpadding="3" width="80%" border="0"><tbody><tr><td bgcolor="#cccccc">public class CoffeeImpSingleton<br />{<br />　　private static CoffeeImp coffeeImp;<br /><br />　　public CoffeeImpSingleton(CoffeeImp coffeeImpIn)<br />　　 {this.coffeeImp = coffeeImpIn;}<br /><br />　　public static CoffeeImp getTheCoffeeImp()<br />　　{<br />　　　　return coffeeImp;<br />　　}<br />}<br /></td></tr></tbody></table><p>看看中杯加奶 和大杯加奶 是怎么出来的:</p><p>//拿出牛奶<br />CoffeeImpSingleton coffeeImpSingleton = new CoffeeImpSingleton(new MilkCoffeeImp());<br /><br />//中杯加奶<br />MediumCoffee mediumCoffee = new MediumCoffee();<br />mediumCoffee.pourCoffee();<br /><br />//大杯加奶<br />SuperSizeCoffee superSizeCoffee = new SuperSizeCoffee();<br />superSizeCoffee.pourCoffee();</p><p>注意: Bridge模式的执行类如CoffeeImp和Coffee是一对一的关系, 正确创建CoffeeImp是该模式的关键,</p><p align="left">Bridge模式在EJB中的应用<br />EJB中有一个Data Access Object (DAO)模式,这是将商业逻辑和具体数据资源分开的,因为不同的数据库有不同的数据库操作.将操作不同数据库的行为独立抽象成一个行为接口DAO.如下:</p><p>1.Business Object (类似Coffee)</p><p>实现一些抽象的商业操作:如寻找一个用户下所有的订单</p><p>涉及数据库操作都使用DAOImplementor.</p><p>2.Data Access Object (类似CoffeeImp)</p><p>一些抽象的对数据库资源操作</p><p>3.DAOImplementor 如OrderDAOCS, OrderDAOOracle, OrderDAOSybase(类似MilkCoffeeImp FragrantCoffeeImp)</p><p>具体的数据库操作,如"INSERT INTO "等语句,OrderDAOOracle是Oracle OrderDAOSybase是Sybase数据库.</p><p>4.数据库 (Cloudscape, Oracle, or Sybase database via JDBC API)</p></div><div></div><img height="1" src="/down_info.asp?id=15417" width="1" border="0" /></td>
										</tr>
								</tbody>
						</table>
				</td>
		</tr>
<img src ="http://www.blogjava.net/RR00/aggbug/72581.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-09-28 15:02 <a href="http://www.blogjava.net/RR00/articles/72581.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>adapter 模式</title><link>http://www.blogjava.net/RR00/articles/72577.html</link><dc:creator>R.Zeus</dc:creator><author>R.Zeus</author><pubDate>Thu, 28 Sep 2006 06:33:00 GMT</pubDate><guid>http://www.blogjava.net/RR00/articles/72577.html</guid><wfw:comment>http://www.blogjava.net/RR00/comments/72577.html</wfw:comment><comments>http://www.blogjava.net/RR00/articles/72577.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/RR00/comments/commentRss/72577.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/RR00/services/trackbacks/72577.html</trackback:ping><description><![CDATA[假设有个class实现的内容正是某个interface想要实现的，但是他们借口不一致，没法直接使用，这时就要使用adapter模式使它们能通用。adapter实现interface，继承或组合class，在实现interface的方法中调用class的方法实现。<br /><br />接口shape 的方法setShape().如果想新建一个shape: textShape,这个textShape很复杂,碰巧以前写过一个TextView类具备textShape的所有功能,但是TextView很明显没有实现(implements)shape接口(很多文章认为接口不一致,接口一致也不能直接用,实现才能直接使用.不一致是个很模糊的概念).所以这时需要使用adapter模式.<br />//implements shape<br />//继承TextView或者用组合<br />public class textShape extends TextView implements shape<br />{<br />    setShape()<br />   {<br />      super.setTextSape();//这里调用TextView完成功能!达到adapter的目的.<br />   }<br />}<img src ="http://www.blogjava.net/RR00/aggbug/72577.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/RR00/" target="_blank">R.Zeus</a> 2006-09-28 14:33 <a href="http://www.blogjava.net/RR00/articles/72577.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>