﻿<?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-黑咖啡-随笔分类-java设计模式</title><link>http://www.blogjava.net/kyleYang/category/43596.html</link><description>孩儿立志出乡关，学不成名誓不还。
风华正茂乾坤地，人生无处不青山。
光阴如同流水去，珍惜时光最宝贵。
鹏程万里靠自己，飞黄腾达青少年。
</description><language>zh-cn</language><lastBuildDate>Wed, 20 Jan 2010 12:02:21 GMT</lastBuildDate><pubDate>Wed, 20 Jan 2010 12:02:21 GMT</pubDate><ttl>60</ttl><item><title>设计模式总结－State模式</title><link>http://www.blogjava.net/kyleYang/archive/2010/01/18/310012.html</link><dc:creator>飞熊</dc:creator><author>飞熊</author><pubDate>Mon, 18 Jan 2010 14:31:00 GMT</pubDate><guid>http://www.blogjava.net/kyleYang/archive/2010/01/18/310012.html</guid><wfw:comment>http://www.blogjava.net/kyleYang/comments/310012.html</wfw:comment><comments>http://www.blogjava.net/kyleYang/archive/2010/01/18/310012.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kyleYang/comments/commentRss/310012.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kyleYang/services/trackbacks/310012.html</trackback:ping><description><![CDATA[
		<a href="/pengpenglin/archive/2008/04/07/191325.html">http://www.blogjava.net/pengpenglin/archive/2008/04/07/191325.html</a>
<img src ="http://www.blogjava.net/kyleYang/aggbug/310012.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kyleYang/" target="_blank">飞熊</a> 2010-01-18 22:31 <a href="http://www.blogjava.net/kyleYang/archive/2010/01/18/310012.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设计模式总结－Strategy模式</title><link>http://www.blogjava.net/kyleYang/archive/2010/01/18/310011.html</link><dc:creator>飞熊</dc:creator><author>飞熊</author><pubDate>Mon, 18 Jan 2010 14:29:00 GMT</pubDate><guid>http://www.blogjava.net/kyleYang/archive/2010/01/18/310011.html</guid><wfw:comment>http://www.blogjava.net/kyleYang/comments/310011.html</wfw:comment><comments>http://www.blogjava.net/kyleYang/archive/2010/01/18/310011.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kyleYang/comments/commentRss/310011.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kyleYang/services/trackbacks/310011.html</trackback:ping><description><![CDATA[
		<a href="/pengpenglin/archive/2008/04/08/191422.html">http://www.blogjava.net/pengpenglin/archive/2008/04/08/191422.html</a>
<img src ="http://www.blogjava.net/kyleYang/aggbug/310011.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kyleYang/" target="_blank">飞熊</a> 2010-01-18 22:29 <a href="http://www.blogjava.net/kyleYang/archive/2010/01/18/310011.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设计模式总结－Visitor模式</title><link>http://www.blogjava.net/kyleYang/archive/2010/01/18/310010.html</link><dc:creator>飞熊</dc:creator><author>飞熊</author><pubDate>Mon, 18 Jan 2010 14:28:00 GMT</pubDate><guid>http://www.blogjava.net/kyleYang/archive/2010/01/18/310010.html</guid><wfw:comment>http://www.blogjava.net/kyleYang/comments/310010.html</wfw:comment><comments>http://www.blogjava.net/kyleYang/archive/2010/01/18/310010.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kyleYang/comments/commentRss/310010.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kyleYang/services/trackbacks/310010.html</trackback:ping><description><![CDATA[
		<a href="/pengpenglin/archive/2008/04/15/193170.html">http://www.blogjava.net/pengpenglin/archive/2008/04/15/193170.html</a>
<img src ="http://www.blogjava.net/kyleYang/aggbug/310010.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kyleYang/" target="_blank">飞熊</a> 2010-01-18 22:28 <a href="http://www.blogjava.net/kyleYang/archive/2010/01/18/310010.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设计模式总结-Composite模式</title><link>http://www.blogjava.net/kyleYang/archive/2010/01/18/310005.html</link><dc:creator>飞熊</dc:creator><author>飞熊</author><pubDate>Mon, 18 Jan 2010 14:04:00 GMT</pubDate><guid>http://www.blogjava.net/kyleYang/archive/2010/01/18/310005.html</guid><wfw:comment>http://www.blogjava.net/kyleYang/comments/310005.html</wfw:comment><comments>http://www.blogjava.net/kyleYang/archive/2010/01/18/310005.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kyleYang/comments/commentRss/310005.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kyleYang/services/trackbacks/310005.html</trackback:ping><description><![CDATA[
		<span style="FONT-SIZE: 10pt">
				<span style="FONT-FAMILY: Verdana">
						<strong>一、Composite模式的定义<br /></strong>
				</span>
		</span>
		<span style="FONT-SIZE: 10pt">
				<span style="FONT-FAMILY: Verdana">
						<br />
						<span style="FONT-SIZE: 10pt">
								<span style="FONT-FAMILY: Verdana">
										<span style="FONT-SIZE: 10pt">
												<span style="FONT-FAMILY: Verdana">
														<span style="BACKGROUND-COLOR: #ffffff">
																<span style="FONT-SIZE: 10pt">
																		<span style="FONT-FAMILY: Verdana">将对象以<span style="COLOR: red"><strong>树形结构</strong></span>组织起来,以达成“部分－整体” 的层次结构，使得客户端对单个对象和组合对象的<strong style="COLOR: red">使用具有一致性</strong>. </span>
																</span>
														</span>
														<br />
														<br />
														<strong>二、Composite模式的特点</strong>
												</span>
										</span>
								</span>
						</span>
				</span>
		</span>
		<p>
				<span style="FONT-SIZE: 10pt">
						<span style="FONT-FAMILY: Verdana">
								<span style="FONT-SIZE: 10pt">
										<span style="FONT-FAMILY: Verdana">
												<span style="FONT-SIZE: 10pt">
														<span style="FONT-FAMILY: Verdana">Composite比较容易理解，想到Composite就应该想到树形结构图。组合体内这些<strong style="COLOR: red">对象都有共同接口</strong>,当组合体一个对象的方法被调用执行时，Composite将<strong style="COLOR: red">遍历</strong>(Iterator)整个树形结构,寻找同样包含这个方法的对象并实现调用执行。可以用牵一动百来形容。</span>
												</span>
										</span>
								</span>
						</span>
				</span>
		</p>
		<p>
				<span style="FONT-SIZE: 10pt">
						<span style="FONT-FAMILY: Verdana">
								<span style="FONT-SIZE: 10pt">
										<span style="FONT-FAMILY: Verdana">
												<span style="FONT-SIZE: 10pt">
														<span style="FONT-FAMILY: Verdana">所以Composite模式使用到Iterator模式，和Chain of Responsibility模式类似。</span>
												</span>
										</span>
								</span>
						</span>
				</span>
		</p>
		<p>
				<span style="FONT-SIZE: 10pt">
						<span style="FONT-FAMILY: Verdana">
								<span style="FONT-SIZE: 10pt">
										<span style="FONT-FAMILY: Verdana">
												<span style="FONT-SIZE: 10pt">
														<span style="FONT-FAMILY: Verdana">
																<strong>三、Composite好处<br /></strong>
																<br />1.使客户端调用简单，客户端可以一致的使用组合结构或其中单个对象，用户就不必关系自己处理的是单个对象还是整个组合结构，这就简化了客户端代码。<br />2.更容易在组合体内加入对象部件. 客户端不必因为加入了新的对象部件而更改代码。</span>
												</span>
										</span>
								</span>
						</span>
				</span>
		</p>
		<p>
				<span style="FONT-SIZE: 10pt">
						<span style="FONT-FAMILY: Verdana">
								<span style="FONT-SIZE: 10pt">
										<span style="FONT-FAMILY: Verdana">
												<span style="FONT-SIZE: 10pt">
														<span style="FONT-FAMILY: Verdana">
																<strong>四、如何使用Composite<br /></strong>
																<br />首先定义一个接口或抽象类，这是设计模式通用方式了，其他设计模式对接口内部定义限制不多，Composite却有个规定，那就是要在接口内部定义一个用于访问和管理Composite组合体的对象们（或称部件Component）.<br /></span>
												</span>
										</span>
								</span>
						</span>
				</span>
		</p>
		<p>
				<span style="FONT-SIZE: 10pt">
						<span style="FONT-FAMILY: Verdana">
								<span style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">    ---- 以上内容摘自Jdon网站的《Gof 23种设计模式》系列文章<br /></span>
								<br />
								<strong>五、Composite模式的分析</strong>
								<br />
								<br />
						</span>
				</span>
				<span style="FONT-SIZE: 10pt">
						<span style="FONT-FAMILY: Verdana">
								<strong>·Composite模式的结构：<br /></strong>基类/接口(构件抽象)<br />    |<br />    |--- 原子构件(extends 基类 / implements 接口)<br />    |<br />    |--- 组合构件(extends 基类 / implements 接口)<br />               |--- 原子构件1<br />               |--- 原子构件2<br />               |--- 组合构件3<br />　　　　　　         |--- 原子构件3-1<br />                        |--- 原子构件3-2<br /><br /></span>
				</span>
				<span style="FONT-SIZE: 10pt">
						<span style="FONT-FAMILY: Verdana">
								<strong>·Composite模式的特点：<br /></strong>   ·Composite模式一般都有一个抽象类或接口来表示最基本的构件。<br />   ·Composite模式一般都由两类对象构成：表示单个元素的对象(Primitive)和表示多个元素组合的对象(Composite)<br />   ·Composite模式下Primitive和Composite对象都继承或实现上层接口或父类<br />   ·Composite模式下每个构件都含有三个基础方法：add(构件)、remove(构件)、iterator()<br />   ·Composite对象含有一个用来保存其下所有基础元素的的集合，例如：Vector，ArrayList，HashMap<br />   ·Composite对象的方法被调用时一般都会引起其下所有基础元素相同方法的调用，即递归调用。<br /><br /><strong>·Composite模式中Primitive对象和Composite对象的方法区别：</strong><br />   ·add(构件)：如果是基础对象，则此方法直接返回false，如果是组合对象，则先添加新构件然后返回true<br />   ·remove(构件)：如果是基础对象，则此方法直接返回false，如果是组合对象，则先删除构件然后返回true<br />   ·iterator()：如果是基础对象，则此方法直接返回null，如果是组合对象，则返回一个包含所有对象的集合<br /><br /></span>
				</span>
				<span style="FONT-SIZE: 10pt">
						<span style="FONT-FAMILY: Verdana">
								<strong>·客户端调用Composite模式的代码示例：<br /></strong>   ·创建一个原子构件对象<br />   ·创建一个组合构件对象<br />   ·调用组合构件对象的add/remove方法添加/删除对象<br />   ·调用组合够对象的iteratore方法迭代显示对象<br />本文摘自：<a href="/pengpenglin/archive/2008/01/21/176675.html">http://www.blogjava.net/pengpenglin/archive/2008/01/21/176675.html</a><br />续：<br /></span>
				</span>
		</p>
		<p>一个二叉树的例子：<br />1.Component 是抽象组件<br />Tree 和Leaf 继承Component <br /><br />private String name; //树或叶子的名称<br />addChild(Component leftChild,Component rightChild); <br />//给一个树上加上一个左孩子，一个右孩子<br />getName(){return name;}<br />getTreeInfo(){} //得到树或叶子的详细信息<br />getLength(); //得到树的高度 <br /><br />2.Tree 二叉树，一个左孩子，一个右孩子 <br /><br />3.Leaf 是叶子节点<br />4.Test 是测试节点 <br /><br />/** Component.java **************/<br />package binarytree;</p>
		<p>public abstract class Component {<br /> private String name;</p>
		<p> public abstract Component addChild(Component leftChild, Component rightChild);</p>
		<p> public String getName() {<br />  return name;<br /> }</p>
		<p> public void getTreeInfo() {<br /> }</p>
		<p> public abstract int getLength();<br />}<br /><br /><br />/** Leaf.java **************/<br />package binarytree;</p>
		<p>public class Leaf extends Component {<br /> private String name;</p>
		<p> private Component leaf = null;</p>
		<p> public Leaf(String name) {<br />  this.name = name;<br /> }</p>
		<p> public Component addChild(Component leftChild, Component rightChild) {<br />  return this;<br /> }</p>
		<p> public String getName() {<br />  return name;<br /> }</p>
		<p> public int getLength() {<br />  return 1;<br /> }</p>
		<p> public static void main(String[] args) {<br /> }<br />}<br /><br />/** Tree.java **************/<br />package binarytree;</p>
		<p>public class Tree extends Component {<br /> private String name;</p>
		<p> private Component leftChild;</p>
		<p> private Component rightChild;</p>
		<p> public Tree(String name, Component leftChild, Component rightChild) {<br />  this.name = name;<br />  this.leftChild = leftChild;<br />  this.rightChild = rightChild;<br /> }</p>
		<p> public Tree(String name) {<br />  this.name = name;<br />  this.leftChild = null;<br />  this.rightChild = null;<br /> }</p>
		<p> public Component addChild(Component leftChild, Component rightChild) {<br />  this.leftChild = leftChild;<br />  this.rightChild = rightChild;<br />  return this;<br /> }</p>
		<p> public String getName() {<br />  return name;<br /> }</p>
		<p> public void getTreeInfo()<br /> // 得到树或叶子的详细信息<br /> // 先打印自己的名字，再遍例左孩子，再遍例右孩子<br /> // 如果左孩子或右孩子是树，递归调用<br /> {<br />  System.out.println(" this trees name is " + getName());<br />  if (this.leftChild instanceof Leaf) {<br />   System.out.println(getName() + "s left child is "<br />     + this.leftChild.getName() + ",it is a Leaf");<br />  }<br />  if (this.leftChild instanceof Tree) {<br />   System.out.println(getName() + "s left child is "<br />     + this.leftChild.getName() + ",it is a Tree");<br />   this.leftChild.getTreeInfo();<br />  }<br />  if (this.leftChild == null) {<br />   System.out.println(getName() + "s left child is a null");<br />  }<br />  if (this.rightChild instanceof Leaf) {<br />   System.out.println(getName() + "s right child is "<br />     + this.rightChild.getName() + ",it is a Leaf");<br />  }<br />  if (this.rightChild instanceof Tree) {<br />   System.out.println(getName() + "s right child is "<br />     + this.rightChild.getName() + ",it is a Tree");<br />   this.rightChild.getTreeInfo();<br />  }<br />  if (this.rightChild == null) {<br />   System.out.println(getName() + "s right child is a null");<br />  }<br />  // System.out.println(getName()+"s 高度 是 "+getLength());<br /> }</p>
		<p> public int getLength() {<br />  // 比较左孩子或右孩子的高度，谁大，+1 返回<br />  // 空孩子的处理<br />  if (this.leftChild == null) {<br />   if (this.rightChild == null)<br />    return 1;<br />   else<br />    return this.rightChild.getLength() + 1;<br />  } else {<br />   if (this.rightChild == null) {<br />    return this.leftChild.getLength() + 1;<br />   } else {<br />    if ((this.leftChild.getLength()) &gt;= (this.rightChild<br />      .getLength()))<br />     return this.leftChild.getLength() + 1;<br />    else<br />     return this.rightChild.getLength() + 1;<br />   }<br />  }<br /> }</p>
		<p> public static void main(String[] args) {<br /> }<br />}<br /><br />/** Test.java 测试类 **************/<br />package binarytree;</p>
		<p>public class Test {</p>
		<p> public Test() {<br /> }</p>
		<p> public static void main(String[] args) {<br />  Component tree = new Tree("luopeng");<br />  Component left_child = new Leaf("luopeng1");<br />  Component right_child = new Leaf("luopeng2");<br />  tree = tree.addChild(left_child, right_child);<br />  // tree=tree.addRightChild(right_child);<br />  tree.getTreeInfo();<br />  Component tree1 = new Tree("luopeng2");<br />  tree1.addChild(tree, left_child);<br />  tree1.getTreeInfo();<br />  Component tree2 = new Tree("luopeng3");<br />  tree2.addChild(tree, null);<br />  tree2.getTreeInfo();<br />  Component tree4 = new Tree("luopeng4");<br />  tree4.addChild(null, tree);<br />  tree4.getTreeInfo();<br />  System.out.println(tree4.getName() + "的高度是 " + tree4.getLength());<br /> }<br />}</p>
<img src ="http://www.blogjava.net/kyleYang/aggbug/310005.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kyleYang/" target="_blank">飞熊</a> 2010-01-18 22:04 <a href="http://www.blogjava.net/kyleYang/archive/2010/01/18/310005.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>迭代器模式(Iterator pattern)</title><link>http://www.blogjava.net/kyleYang/archive/2010/01/18/310004.html</link><dc:creator>飞熊</dc:creator><author>飞熊</author><pubDate>Mon, 18 Jan 2010 13:51:00 GMT</pubDate><guid>http://www.blogjava.net/kyleYang/archive/2010/01/18/310004.html</guid><wfw:comment>http://www.blogjava.net/kyleYang/comments/310004.html</wfw:comment><comments>http://www.blogjava.net/kyleYang/archive/2010/01/18/310004.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kyleYang/comments/commentRss/310004.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kyleYang/services/trackbacks/310004.html</trackback:ping><description><![CDATA[
		<div class="cnt" id="blog_text">
				<p>
						<strong>一、 引言</strong>
						<br />　　迭代这个名词对于熟悉Java的人来说绝对不陌生。我们常常使用JDK提供的迭代接口进行java collection的遍历：<br />Iterator it = list.iterator();<br />while(it.hasNext()){<br />　//using “it.next();”do some businesss logic<br />}<br />而这就是关于迭代器模式应用很好的例子。<br /><br />　　<strong>二、 定义与结构</strong><br /><br />　　迭代器（Iterator）模式，又叫做游标（Cursor）模式。GOF给出的定义为：提供一种方法访问一个容器（container）对象中各个元素，而又不需暴露该对象的内部细节。<br /><br />　　从定义可见，迭代器模式是为容器而生。很明显，对容器对象的访问必然涉及到遍历算法。你可以一股脑的将遍历方法塞到容器对象中去；或者根本不去提供什么遍历算法，让使用容器的人自己去实现去吧。这两种情况好像都能够解决问题。<br /><br />　　然而在前一种情况，容器承受了过多的功能，它不仅要负责自己“容器”内的元素维护（添加、删除等等），而且还要提供遍历自身的接口；而且由于遍历状态保存的问题，不能对同一个容器对象同时进行多个遍历。第二种方式倒是省事，却又将容器的内部细节暴露无遗。<br /><br />　　而迭代器模式的出现，很好的解决了上面两种情况的弊端。先来看下迭代器模式的真面目吧。 <br /><br />　　迭代器模式由以下角色组成：<br /><br />　　1) 迭代器角色（Iterator）：迭代器角色负责定义访问和遍历元素的接口。<br /><br />　　2) 具体迭代器角色（Concrete Iterator）：具体迭代器角色要实现迭代器接口，并要记录遍历中的当前位置。<br /><br />　　3) 容器角色（Container）：容器角色负责提供创建具体迭代器角色的接口。<br /><br />　　4) 具体容器角色（Concrete Container）：具体容器角色实现创建具体迭代器角色的接口——这个具体迭代器角色于该容器的结构相关。<br /><br />　　迭代器模式的类图如下：<br /><br /></p>
				<table width="90%" align="center" border="0">
						<tbody>
								<tr>
										<td>
												<div align="center">
														<div align="center">
																<img alt="" src="http://dev.yesky.com/imagelist/05/10/7k2946abt12n.jpg" />
														</div>
												</div>
										</td>
								</tr>
						</tbody>
				</table>
				<br />　　从结构上可以看出，迭代器模式在客户与容器之间加入了迭代器角色。迭代器角色的加入，就可以很好的避免容器内部细节的暴露，而且也使得设计符号“单一职责原则”。<br /><br />　　注意，在迭代器模式中，具体迭代器角色和具体容器角色是耦合在一起的——遍历算法是与容器的内部细节紧密相关的。为了使客户程序从与具体迭代器角色耦合的困境中脱离出来，避免具体迭代器角色的更换给客户程序带来的修改，迭代器模式抽象了具体迭代器角色，使得客户程序更具一般性和重用性。这被称为多态迭代。<br /><br />　　<strong>三、 举例</strong><br /><br />　　由于迭代器模式本身的规定比较松散，所以具体实现也就五花八门。我们在此仅举一例，根本不能将实现方式一一呈现。因此在举例前，我们先来列举下迭代器模式的实现方式。 <br /><br />　　1．迭代器角色定义了遍历的接口，但是没有规定由谁来控制迭代。在Java collection的应用中，是由客户程序来控制遍历的进程，被称为外部迭代器；还有一种实现方式便是由迭代器自身来控制迭代，被称为内部迭代器。外部迭代器要比内部迭代器灵活、强大，而且内部迭代器在java语言环境中，可用性很弱。<br /><br />　　2．在迭代器模式中没有规定谁来实现遍历算法。好像理所当然的要在迭代器角色中实现。因为既便于一个容器上使用不同的遍历算法，也便于将一种遍历算法应用于不同的容器。但是这样就破坏掉了容器的封装——容器角色就要公开自己的私有属性，在java中便意味着向其他类公开了自己的私有属性。<br /><br />　　那我们把它放到容器角色里来实现好了。这样迭代器角色就被架空为仅仅存放一个遍历当前位置的功能。但是遍历算法便和特定的容器紧紧绑在一起了。<br /><br />　　而在Java Collection的应用中，提供的具体迭代器角色是定义在容器角色中的内部类。这样便保护了容器的封装。但是同时容器也提供了遍历算法接口，你可以扩展自己的迭代器。<br /><br />　　好了，我们来看下Java Collection中的迭代器是怎么实现的吧。<br />//迭代器角色，仅仅定义了遍历接口<p>public interface Iterator {<br />　boolean hasNext();<br />　Object next();<br />　void remove();<br />}</p><p>//容器角色，这里以List为例。它也仅仅是一个接口，就不罗列出来了<br />//具体容器角色，便是实现了List接口的ArrayList等类。为了突出重点这里指罗列和迭代器相关的内容<br />//具体迭代器角色，它是以内部类的形式出来的。AbstractList是为了将各个具体容器角色的公共部分提取出来而存在的。</p><p>public abstract class AbstractList extends AbstractCollection implements List {<br />…… <br />//这个便是负责创建具体迭代器角色的工厂方法<br />public Iterator iterator() {<br />　return new Itr();<br />}</p><p>//作为内部类的具体迭代器角色</p><p>private class Itr implements Iterator {<br />　int cursor = 0;<br />　int lastRet = -1;<br />　int expectedModCount = modCount;</p><p>　public boolean hasNext() {<br />　　return cursor != size();<br />　}</p><p>　public Object next() {<br />　　checkForComodification();<br />　　try {<br />　　　Object next = get(cursor);<br />　　　lastRet = cursor++;<br />　　　return next;<br />　　} catch(IndexOutOfBoundsException e) {<br />　　　checkForComodification();<br />　　　throw new NoSuchElementException();<br />　　}<br />　}</p><p>　public void remove() {<br />　　if (lastRet == -1)<br />　　　throw new IllegalStateException();<br />　　　checkForComodification();</p><p>　　try {<br />　　　AbstractList.this.remove(lastRet);<br />　　　if (lastRet &lt; cursor)<br />　　　　cursor--;<br />　　　lastRet = -1;<br />　　　expectedModCount = modCount;<br />　　} catch(IndexOutOfBoundsException e) {<br />　　　throw new ConcurrentModificationException();<br />　　}<br />　}</p><p>　final void checkForComodification() {<br />　　if (modCount != expectedModCount)<br />　　　throw new ConcurrentModificationException();<br />　}<br />}<br />至于迭代器模式的使用。正如引言中所列那样，客户程序要先得到具体容器角色，然后再通过具体容器角色得到具体迭代器角色。这样便可以使用具体迭代器角色来遍历容器了……<br /><br />　　四、 实现自己的迭代器<br /><br />　　在实现自己的迭代器的时候，一般要操作的容器有支持的接口才可以。而且我们还要注意以下问题： <br /><br />　　在迭代器遍历的过程中，通过该迭代器进行容器元素的增减操作是否安全呢？<br /><br />　　在容器中存在复合对象的情况，迭代器怎样才能支持深层遍历和多种遍历呢？<br /><br />　　以上两个问题对于不同结构的容器角色，各不相同，值得考虑。<br /><br />　　五、 适用情况 <br /><br />　　由上面的讲述，我们可以看出迭代器模式给容器的应用带来以下好处：<br /><br />　　1) 支持以不同的方式遍历一个容器角色。根据实现方式的不同，效果上会有差别。<br /><br />　　2) 简化了容器的接口。但是在java Collection中为了提高可扩展性，容器还是提供了遍历的接口。<br /><br />　　3) 对同一个容器对象，可以同时进行多个遍历。因为遍历状态是保存在每一个迭代器对象中的。<br /><br />　　由此也能得出迭代器模式的适用范围：<br /><br />　　1) 访问一个容器对象的内容而无需暴露它的内部表示。<br /><br />　　2) 支持对容器对象的多种遍历。<br /><br />　　3) 为遍历不同的容器结构提供一个统一的接口（多态迭代）。<br /><br />实例：<br /></p></div>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff">public class IteratorDemo {<br /> private List&lt;String&gt; strList;</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff"> public IteratorDemo() {<br />  strList = new ArrayList&lt;String&gt;();<br /> }</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff"> public void add(String item) {<br />  strList.add(item);<br /> }</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff"> public String remove(int index) {<br />  String item = strList.get(index);<br />  strList.remove(index);<br />  return item;<br /> }</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff"> public Iterator&lt;String&gt; iterator() {<br />  return new Iterator&lt;String&gt;() {<br />   // 游标<br />   private int cursor = 0;</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff">   public boolean hasNext() {<br />    return cursor &lt; strList.size();<br />   }</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff">   public String next() {<br />    return strList.get(cursor++);<br />   }</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff">   public void remove() {</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff">   }</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff">  };<br /> }</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff"> public static void main(String[] args) {<br />  IteratorDemo demo = new IteratorDemo();<br />  demo.add("1");<br />  demo.add("2");<br />  demo.add("3");<br />  demo.add("4");</font>
		</p>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff">  Iterator&lt;String&gt; iterator = demo.iterator();<br />  while (iterator.hasNext()) {<br />   System.out.println(iterator.next());<br />  }<br /> }<br />}</font>
		</p>
<img src ="http://www.blogjava.net/kyleYang/aggbug/310004.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kyleYang/" target="_blank">飞熊</a> 2010-01-18 21:51 <a href="http://www.blogjava.net/kyleYang/archive/2010/01/18/310004.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java设计模式使用率排行榜</title><link>http://www.blogjava.net/kyleYang/archive/2010/01/17/309894.html</link><dc:creator>飞熊</dc:creator><author>飞熊</author><pubDate>Sun, 17 Jan 2010 14:28:00 GMT</pubDate><guid>http://www.blogjava.net/kyleYang/archive/2010/01/17/309894.html</guid><wfw:comment>http://www.blogjava.net/kyleYang/comments/309894.html</wfw:comment><comments>http://www.blogjava.net/kyleYang/archive/2010/01/17/309894.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kyleYang/comments/commentRss/309894.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kyleYang/services/trackbacks/309894.html</trackback:ping><description><![CDATA[
		<p>Java设计模式使用率爬行榜</p>
		<table border="1">
				<tbody>
						<tr>
								<td>使用频率</td>
								<td width="42">所属类型</td>
								<td width="101">模式名称</td>
								<td width="53">模式</td>
								<td width="423">简单定义</td>
						</tr>
						<tr>
								<td>5</td>
								<td width="42">创建型</td>
								<td width="101">Singleton</td>
								<td width="53">单例模式</td>
								<td width="423">保证一个类只有一个实例，并提供一个访问它的全局访问点。</td>
						</tr>
						<tr>
								<td>5</td>
								<td width="42">结构型</td>
								<td width="101">Composite</td>
								<td width="53">复合模式</td>
								<td width="423">将对象组合成树形结构以表示部分整体的关系，Composite使得用户对单个对象和组合对象的使用具有一致性。</td>
						</tr>
						<tr>
								<td>5</td>
								<td width="42">结构型</td>
								<td width="101">FASADE</td>
								<td width="53">面模式</td>
								<td width="423">为子系统中的一组接口提供一致的界面，fasade提供了一高层接口，这个接口使得子系统更容易使用。</td>
						</tr>
						<tr>
								<td>5</td>
								<td width="42">结构型</td>
								<td width="101">Proxy</td>
								<td width="53">代理</td>
								<td width="423">为其他对象提供一种代理以控制对这个对象的访问</td>
						</tr>
						<tr>
								<td>5</td>
								<td width="42">行为型</td>
								<td width="101">Iterator</td>
								<td width="53">迭代器</td>
								<td width="423">提供一个方法顺序访问一个聚合对象的各个元素，而又不需要暴露该对象的内部表示。</td>
						</tr>
						<tr>
								<td>5</td>
								<td width="42">行为型</td>
								<td width="101">Observer</td>
								<td width="53">观察者</td>
								<td width="423">定义对象间一对多的依赖关系，当一个对象的状态发生改变时，所有依赖于它的对象都得到通知自动更新。</td>
						</tr>
						<tr>
								<td>5</td>
								<td width="42">行为型</td>
								<td width="101">Template Method</td>
								<td width="53">模板方法</td>
								<td width="423">定义一个操作中的算法的骨架，而将一些步骤延迟到子类中，TemplateMethod使得子类可以不改变一个算法的结构即可以重定义该算法得某些特定步骤。</td>
						</tr>
						<tr>
								<td>4</td>
								<td width="42">创建型</td>
								<td width="101">Abstract Factory</td>
								<td width="53">抽象工厂</td>
								<td width="423">提供一个创建一系列相关或相互依赖对象的接口，而无须指定它们的具体类。</td>
						</tr>
						<tr>
								<td>4</td>
								<td width="42">创建型</td>
								<td width="101">Factory Method</td>
								<td width="53">工厂方法</td>
								<td width="423">定义一个用于创建对象的接口，让子类决定实例化哪一个类，Factory Method使一个类的实例化延迟到了子类。</td>
						</tr>
						<tr>
								<td>4</td>
								<td width="42">结构型</td>
								<td width="101">Adapter</td>
								<td width="53">适配器</td>
								<td width="423">将一类的接口转换成客户希望的另外一个接口，Adapter模式使得原本由于接口不兼容而不能一起工作那些类可以一起工作。</td>
						</tr>
						<tr>
								<td>4</td>
								<td width="42">结构型</td>
								<td width="101">Decrator</td>
								<td width="53">装饰模式</td>
								<td width="423">动态地给一个对象增加一些额外的职责，就增加的功能来说，Decorator模式相比生成子类更加灵活。</td>
						</tr>
						<tr>
								<td>4</td>
								<td width="42">行为型</td>
								<td width="101">Command</td>
								<td width="53">指令模式</td>
								<td width="423">将一个请求封装为一个对象，从而使你可以用不同的请求对客户进行参数化，对请求排队和记录请求日志，以及支持可撤销的操作。</td>
						</tr>
						<tr>
								<td>4</td>
								<td width="42">行为型</td>
								<td width="101">State</td>
								<td width="53">状态模式</td>
								<td width="423">允许对象在其内部状态改变时改变他的行为。对象看起来似乎改变了他的类。</td>
						</tr>
						<tr>
								<td>4</td>
								<td width="42">行为型</td>
								<td width="101">Strategy</td>
								<td width="53">策略模式</td>
								<td width="423">定义一系列的算法，把他们一个个封装起来，并使他们可以互相替换，本模式使得算法可以独立于使用它们的客户。</td>
						</tr>
						<tr>
								<td>3</td>
								<td width="42">创建型</td>
								<td width="101">Builder</td>
								<td width="53">生成器</td>
								<td width="423">将一个复杂对象的构建与他的表示相分离，使得同样的构建过程可以创建不同的表示。</td>
						</tr>
						<tr>
								<td>3</td>
								<td width="42">结构型</td>
								<td width="101">Bridge</td>
								<td width="53">桥模式</td>
								<td width="423">将抽象部分与它的实现部分相分离，使他们可以独立的变化。</td>
						</tr>
						<tr>
								<td>3</td>
								<td width="42">行为型</td>
								<td width="101">Chain of Responsibility</td>
								<td width="53">职责链</td>
								<td width="423">使多个对象都有机会处理请求，从而避免请求的送发者和接收者之间的耦合关系</td>
						</tr>
						<tr>
								<td>2</td>
								<td width="42">创建型</td>
								<td width="101">Prototype</td>
								<td width="53">原型</td>
								<td width="423">用原型实例指定创建对象的种类，并且通过拷贝这些原型来创建新的对象。</td>
						</tr>
						<tr>
								<td>2</td>
								<td width="42">结构型</td>
								<td width="101">Flyweight</td>
								<td width="53">享元</td>
								<td width="423"> </td>
						</tr>
						<tr>
								<td>2</td>
								<td width="42">行为型</td>
								<td width="101">Mediator</td>
								<td width="53">中介者</td>
								<td width="423">用一个中介对象封装一些列的对象交互。</td>
						</tr>
						<tr>
								<td>2</td>
								<td width="42">行为型</td>
								<td width="101">Visitor</td>
								<td width="53">访问者</td>
								<td width="423">表示一个作用于某对象结构中的各元素的操作，它使你可以在不改变各元素类的前提下定义作用于这个元素的新操作。</td>
						</tr>
						<tr>
								<td>1</td>
								<td width="42">行为型</td>
								<td width="101">Interpreter</td>
								<td width="53">解释器</td>
								<td width="423">给定一个语言，定义他的文法的一个表示，并定义一个解释器，这个解释器使用该表示来解释语言中的句子。</td>
						</tr>
						<tr>
								<td>1</td>
								<td width="42">行为型</td>
								<td width="101">Memento</td>
								<td width="53">备忘录</td>
								<td width="423">在不破坏对象的前提下，捕获一个对象的内部状态，并在该对象之外保存这个状态。</td>
						</tr>
				</tbody>
		</table>
		<p>转自2004年6期《CSDN开发高手》</p>
<img src ="http://www.blogjava.net/kyleYang/aggbug/309894.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kyleYang/" target="_blank">飞熊</a> 2010-01-17 22:28 <a href="http://www.blogjava.net/kyleYang/archive/2010/01/17/309894.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java解读--桥接Bridge</title><link>http://www.blogjava.net/kyleYang/archive/2010/01/17/309880.html</link><dc:creator>飞熊</dc:creator><author>飞熊</author><pubDate>Sun, 17 Jan 2010 12:39:00 GMT</pubDate><guid>http://www.blogjava.net/kyleYang/archive/2010/01/17/309880.html</guid><wfw:comment>http://www.blogjava.net/kyleYang/comments/309880.html</wfw:comment><comments>http://www.blogjava.net/kyleYang/archive/2010/01/17/309880.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kyleYang/comments/commentRss/309880.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kyleYang/services/trackbacks/309880.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1、核心意图：				将抽象部分和实现部分分离，使它们都可以独立的变化。		该模式的目标是通过把高层的抽象和底层的实现分开，分别构建自己的类层次结构，并通过实现部分的接口将两部分进行桥接，从而达到高层抽象和底层实现可以独立的方便扩展的目的。其核心是分离，和委托。		 						2、身边实例：				Java语言的一个非常重要的特点是平台的无关性，对于一般的高级语言...&nbsp;&nbsp;<a href='http://www.blogjava.net/kyleYang/archive/2010/01/17/309880.html'>阅读全文</a><img src ="http://www.blogjava.net/kyleYang/aggbug/309880.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kyleYang/" target="_blank">飞熊</a> 2010-01-17 20:39 <a href="http://www.blogjava.net/kyleYang/archive/2010/01/17/309880.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>观察者模式-Java自定义事件</title><link>http://www.blogjava.net/kyleYang/archive/2010/01/17/309871.html</link><dc:creator>飞熊</dc:creator><author>飞熊</author><pubDate>Sun, 17 Jan 2010 10:15:00 GMT</pubDate><guid>http://www.blogjava.net/kyleYang/archive/2010/01/17/309871.html</guid><wfw:comment>http://www.blogjava.net/kyleYang/comments/309871.html</wfw:comment><comments>http://www.blogjava.net/kyleYang/archive/2010/01/17/309871.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kyleYang/comments/commentRss/309871.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kyleYang/services/trackbacks/309871.html</trackback:ping><description><![CDATA[
		<dd>
				<div class="Description">核心提示：观察者模式-Java自定义事件 [正文]: MyEventTest.java: package wintys.event; import javax.swing.event.EventListenerList; import java.util.Date; import java.text.DateFormat; import java.text.SimpleDateFormat; /** *Java的事件机制/自定义事件. 运 <br /><a class="postTitle2" id="viewpost1_TitleUrl" href="/wintys/archive/2009/10/11/pattern_observer_event.html"><font color="#000000"><strong>观察者模式-Java自定义事件</strong></font></a><strong> <br /><br /></strong>MyEventTest.java: <br /></div>
		</dd>
		<dd class="ArticleContent">
				<div class="postTitle">
						<ol class="dp-j">
								<li class="alt">
										<span>
												<span class="keyword">package</span>
												<span> wintys.event;    </span>
										</span>
								</li>
								<li>
										<span>import</span>
										<span> javax.swing.event.EventListenerList;    </span>
								</li>
								<li class="alt">
										<span>import</span>
										<span> java.util.Date;    </span>
								</li>
								<li>
										<span>import</span>
										<span> java.text.DateFormat;    </span>
								</li>
								<li class="alt">
										<span>import</span>
										<span> java.text.SimpleDateFormat;    </span>
								</li>
								<li>
										<span>  </span>
								</li>
								<li class="alt">
										<span>/**  </span>  
</li>
								<li>
										<span>
												<span class="comment">* Java的事件机制/自定义事件.  </span> </span>
								</li>
								<li class="alt">
										<span>
												<span class="comment">
												</span>
										</span>
								</li>
								<li>
										<span>
												<span class="comment">运行结果:  </span> </span>
								</li>
								<li class="alt">
										<span>
												<span class="comment">do something interesting in source here.  </span> </span>
								</li>
								<li>
										<span>
												<span class="comment">listener detects [event]:wintys.event.MyEvent[source=wintys.event.MySource@18158  </span> </span>
								</li>
								<li class="alt">
										<span>
												<span class="comment">59] [occur at]:2009-10-11 16:27:49  </span> </span>
								</li>
								<li>
										<span>
												<span class="comment">listener detects [event]:wintys.event.MyEvent[source=wintys.event.MySource@18158  </span> </span>
								</li>
								<li class="alt">
										<span>
												<span class="comment">59] [occur at]:2009-10-11 16:27:49  </span> </span>
								</li>
								<li>
										<span>
												<span class="comment">
												</span>
										</span>
								</li>
								<li class="alt">
										<span>
												<span class="comment">* @version 2009-10-11  </span> </span>
								</li>
								<li>
										<span>
												<span class="comment">* @author 天堂露珠 (wintys@gmail.com)  </span> </span>
								</li>
								<li class="alt">
										<span>
												<span class="comment">* @see http://www.blogjava.net/wintys  </span> </span>
								</li>
								<li>
										<span>
												<span class="comment">*/</span>
												<span>    </span>
										</span>
								</li>
								<li class="alt">
										<span>class</span>
										<span> MyEventTest{    </span>
								</li>
								<li>
										<span>    </span>
										<span class="keyword">public</span>
										<span> </span>
										<span class="keyword">static</span>
										<span> </span>
										<span class="keyword">void</span>
										<span> main(String[] args){    </span>
								</li>
								<li class="alt">
										<span>        MySource source = </span>
										<span class="keyword">new</span>
										<span> MySource();    </span>
								</li>
								<li>
										<span>        MyListener myListener = </span>
										<span class="keyword">new</span>
										<span> MyListener(){    </span>
								</li>
								<li class="alt">
										<span>            </span>
										<span class="keyword">public</span>
										<span> </span>
										<span class="keyword">void</span>
										<span> doMyAction(MyEvent e){    </span>
								</li>
								<li>
										<span>                System.out.println(</span>
										<span class="string">"listener detects "</span>
										<span> + e);    </span>
								</li>
								<li class="alt">
										<span>            }    </span>
								</li>
								<li>
										<span>        };    </span>
								</li>
								<li class="alt">
										<span>        source.addMyListener(myListener);    </span>
								</li>
								<li>
										<span>        source.addMyListener(myListener);    </span>
								</li>
								<li class="alt">
										<span>        source.addMyListener(myListener);    </span>
								</li>
								<li>
										<span>        source.removeMyListener(myListener);    </span>
								</li>
								<li class="alt">
										<span>  </span>
								</li>
								<li>
										<span>        source.doSomething();    </span>
								</li>
								<li class="alt">
										<span>    }    </span>
								</li>
								<li>
										<span>}    </span>
								</li>
								<li class="alt">
										<span>  </span>
								</li>
								<li>
										<span>/**  </span>  
</li>
								<li class="alt">
										<span>
												<span class="comment">* 自定义的事件.  </span> </span>
								</li>
								<li>
										<span>
												<span class="comment">* @version 2009-10-11  </span> </span>
								</li>
								<li class="alt">
										<span>
												<span class="comment">* @author 天堂露珠(wintys@gmail.com)  </span> </span>
								</li>
								<li>
										<span>
												<span class="comment">* @see http://www.blogjava.net/wintys  </span> </span>
								</li>
								<li class="alt">
										<span>
												<span class="comment">*/</span>
												<span>    </span>
										</span>
								</li>
								<li>
										<span>class</span>
										<span> MyEvent </span>
										<span class="keyword">extends</span>
										<span> java.util.EventObject{    </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="keyword">private</span>
										<span> Date date;</span>
										<span class="comment">//记录事件发生的时间  </span>
										<span>  </span>
								</li>
								<li>
										<span>  </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="keyword">public</span>
										<span> MyEvent(Object source , Date date){    </span>
								</li>
								<li>
										<span>        </span>
										<span class="keyword">super</span>
										<span>(source);    </span>
								</li>
								<li class="alt">
										<span>  </span>
								</li>
								<li>
										<span>        </span>
										<span class="keyword">this</span>
										<span>.date = date;    </span>
								</li>
								<li class="alt">
										<span>    }    </span>
								</li>
								<li>
										<span>  </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="keyword">public</span>
										<span> String toString(){    </span>
								</li>
								<li>
										<span>        DateFormat df = </span>
										<span class="keyword">new</span>
										<span> SimpleDateFormat(</span>
										<span class="string">"yyyy-MM-dd HH:mm:ss"</span>
										<span>);    </span>
								</li>
								<li class="alt">
										<span>        String dt = df.format(date);    </span>
								</li>
								<li>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="keyword">return</span>
										<span> </span>
										<span class="string">"[event]:"</span>
										<span> + </span>
										<span class="keyword">super</span>
										<span>.toString() + </span>
										<span class="string">" [occur at]:"</span>
										<span> + dt;    </span>
								</li>
								<li>
										<span>    }    </span>
								</li>
								<li class="alt">
										<span>}    </span>
								</li>
								<li>
										<span>  </span>
								</li>
								<li class="alt">
										<span>/**  </span>  
</li>
								<li>
										<span>
												<span class="comment">* 自定义事件监听器接口.  </span> </span>
								</li>
								<li class="alt">
										<span>
												<span class="comment">* @version 2009-10-11  </span> </span>
								</li>
								<li>
										<span>
												<span class="comment">* @author 天堂露珠(wintys@gmail.com)  </span> </span>
								</li>
								<li class="alt">
										<span>
												<span class="comment">* @see http://www.blogjava.net/wintys  </span> </span>
								</li>
								<li>
										<span>
												<span class="comment">*/</span>
												<span>    </span>
										</span>
								</li>
								<li class="alt">
										<span>interface</span>
										<span> MyListener </span>
										<span class="keyword">extends</span>
										<span> java.util.EventListener{    </span>
								</li>
								<li>
										<span>    </span>
										<span class="keyword">void</span>
										<span> doMyAction(MyEvent e);    </span>
								</li>
								<li class="alt">
										<span>}    </span>
								</li>
								<li>
										<span>  </span>
								</li>
								<li class="alt">
										<span>/**  </span>  
</li>
								<li>
										<span>
												<span class="comment">* 自定义事件源.  </span> </span>
								</li>
								<li class="alt">
										<span>
												<span class="comment">* @version 2009-10-11  </span> </span>
								</li>
								<li>
										<span>
												<span class="comment">* @author 天堂露珠(wintys@gmail.com)  </span> </span>
								</li>
								<li class="alt">
										<span>
												<span class="comment">* @see http://www.blogjava.net/wintys  </span> </span>
								</li>
								<li>
										<span>
												<span class="comment">*/</span>
												<span>    </span>
										</span>
								</li>
								<li class="alt">
										<span>class</span>
										<span> MySource{    </span>
								</li>
								<li>
										<span>    </span>
										<span class="comment">/**  </span>  
</li>
								<li class="alt">
										<span>
												<span class="comment">     * 保存注册的监听器列表.  </span> </span>
								</li>
								<li>
										<span>
												<span class="comment">     * 子类可以使用它保存自己的事件监听器(非MyListener监听器)列表.  </span> </span>
								</li>
								<li class="alt">
										<span>
												<span class="comment">     */</span>
												<span>    </span>
										</span>
								</li>
								<li>
										<span>    </span>
										<span class="keyword">protected</span>
										<span> EventListenerList listenerList = </span>
										<span class="keyword">new</span>
										<span> EventListenerList();    </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="keyword">private</span>
										<span> MyEvent myEvent = </span>
										<span class="keyword">null</span>
										<span>;</span>
										<span class="comment">//fireDoMyAction()使用此变量  </span>
										<span>  </span>
								</li>
								<li>
										<span>  </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="comment">/**  </span>  
</li>
								<li>
										<span>
												<span class="comment">     * 没有做任何事  </span> </span>
								</li>
								<li class="alt">
										<span>
												<span class="comment">     */</span>
												<span>    </span>
										</span>
								</li>
								<li>
										<span>    </span>
										<span class="keyword">public</span>
										<span> MySource(){    </span>
								</li>
								<li class="alt">
										<span>    }    </span>
								</li>
								<li>
										<span>    </span>
										<span class="comment">/**  </span>  
</li>
								<li class="alt">
										<span>
												<span class="comment">     * 添加一个MyListener监听器  </span> </span>
								</li>
								<li>
										<span>
												<span class="comment">     */</span>
												<span>    </span>
										</span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="keyword">public</span>
										<span> </span>
										<span class="keyword">void</span>
										<span> addMyListener(MyListener listener){    </span>
								</li>
								<li>
										<span>        listenerList.add(MyListener.</span>
										<span class="keyword">class</span>
										<span> , listener);    </span>
								</li>
								<li class="alt">
										<span>    }    </span>
								</li>
								<li>
										<span>  </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="comment">/**  </span>  
</li>
								<li>
										<span>
												<span class="comment">     * 移除一个已注册的MyListener监听器.  </span> </span>
								</li>
								<li class="alt">
										<span>
												<span class="comment">     * 如果监听器列表中已有相同的监听器listener1、listener2,  </span> </span>
								</li>
								<li>
										<span>
												<span class="comment">     * 并且listener1==listener2,  </span> </span>
								</li>
								<li class="alt">
										<span>
												<span class="comment">     * 那么只移除最近注册的一个监听器。  </span> </span>
								</li>
								<li>
										<span>
												<span class="comment">     */</span>
												<span>    </span>
										</span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="keyword">public</span>
										<span> </span>
										<span class="keyword">void</span>
										<span> removeMyListener(MyListener listener){    </span>
								</li>
								<li>
										<span>        listenerList.remove(MyListener.</span>
										<span class="keyword">class</span>
										<span> , listener);    </span>
								</li>
								<li class="alt">
										<span>    }    </span>
								</li>
								<li>
										<span>  </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="comment">/**  </span>  
</li>
								<li>
										<span>
												<span class="comment">     * @return 在此对象上监听的所有MyListener类型的监听器  </span> </span>
								</li>
								<li class="alt">
										<span>
												<span class="comment">     */</span>
												<span>    </span>
										</span>
								</li>
								<li>
										<span>    </span>
										<span class="keyword">public</span>
										<span> MyListener[] getMyListeners(){    </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="keyword">return</span>
										<span> (MyListener[])listenerList.getListeners(MyListener.</span>
										<span class="keyword">class</span>
										<span>);    </span>
								</li>
								<li>
										<span>    }    </span>
								</li>
								<li class="alt">
										<span>  </span>
								</li>
								<li>
										<span>    </span>
										<span class="comment">//Winty:Copy directly from javax.swing.event.EventListenerList  </span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="comment">/*Notify all listeners that have registered interest for  </span>  
</li>
								<li>
										<span>
												<span class="comment">       notification on this event type.  The event instance  </span> </span>
								</li>
								<li class="alt">
										<span>
												<span class="comment">       is lazily created using the parameters passed into  </span> </span>
								</li>
								<li>
										<span>
												<span class="comment">       the fire method.  </span> </span>
								</li>
								<li class="alt">
										<span>
												<span class="comment">     */</span>
												<span>    </span>
										</span>
								</li>
								<li>
										<span>    </span>
										<span class="keyword">protected</span>
										<span> </span>
										<span class="keyword">void</span>
										<span> fireDoMyAction() {    </span>
								</li>
								<li class="alt">
										<span>         </span>
										<span class="comment">// getListenerList() Guaranteed to return a non-null array  </span>
										<span>  </span>
								</li>
								<li>
										<span>         Object[] listeners = listenerList.getListenerList();    </span>
								</li>
								<li class="alt">
										<span>         </span>
										<span class="comment">// Process the listeners last to first, notifying  </span>
										<span>  </span>
								</li>
								<li>
										<span>         </span>
										<span class="comment">// those that are interested in this event  </span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>        </span>
										<span class="keyword">for</span>
										<span> (</span>
										<span class="keyword">int</span>
										<span> i = listeners.length-</span>
										<span class="number">2</span>
										<span>; i&gt;=</span>
										<span class="number">0</span>
										<span>; i-=</span>
										<span class="number">2</span>
										<span>) {    </span>
								</li>
								<li>
										<span>            </span>
										<span class="keyword">if</span>
										<span> (listeners[i]==MyListener.</span>
										<span class="keyword">class</span>
										<span>) {    </span>
								</li>
								<li class="alt">
										<span>                </span>
										<span class="comment">// Lazily create the event:  </span>
										<span>  </span>
								</li>
								<li>
										<span>                </span>
										<span class="keyword">if</span>
										<span> (myEvent == </span>
										<span class="keyword">null</span>
										<span>)    </span>
								</li>
								<li class="alt">
										<span>                    myEvent = </span>
										<span class="keyword">new</span>
										<span> MyEvent(</span>
										<span class="keyword">this</span>
										<span> , </span>
										<span class="keyword">new</span>
										<span> Date());    </span>
								</li>
								<li>
										<span>                ((MyListener)listeners[i+</span>
										<span class="number">1</span>
										<span>]).doMyAction(myEvent);    </span>
								</li>
								<li class="alt">
										<span>            }    </span>
								</li>
								<li>
										<span>        }    </span>
								</li>
								<li class="alt">
										<span>    }    </span>
								</li>
								<li>
										<span>  </span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="comment">/**  </span>  
</li>
								<li>
										<span>
												<span class="comment">     * 做一些事件源应该做的有意义的事，然后通知监听器.  </span> </span>
								</li>
								<li class="alt">
										<span>
												<span class="comment">     * 这里只是一个示例方法.  </span> </span>
								</li>
								<li>
										<span>
												<span class="comment">     * 例如:MySource如果是一个按钮，则doSomething()就可以命名为click(),  </span> </span>
								</li>
								<li class="alt">
										<span>
												<span class="comment">     * 当用户点击按钮时调用click()方法.  </span> </span>
								</li>
								<li>
										<span>
												<span class="comment">     */</span>
												<span>    </span>
										</span>
								</li>
								<li class="alt">
										<span>    </span>
										<span class="keyword">public</span>
										<span> </span>
										<span class="keyword">void</span>
										<span> doSomething() {    </span>
								</li>
								<li>
										<span>        System.out.println(</span>
										<span class="string">"do something interesting here."</span>
										<span>);    </span>
								</li>
								<li class="alt">
										<span>  </span>
								</li>
								<li>
										<span>        fireDoMyAction();</span>
										<span class="comment">//通知监听器  </span>
										<span>  </span>
								</li>
								<li class="alt">
										<span>    }    </span>
								</li>
								<li>
										<span>}   </span>
								</li>
						</ol>
				</div>
				<strong>
						<span>
						</span>
				</strong>
				<p>
						<br />
						<strong>         EventListenerList是特别需要说明的，它内部使用一个Object数组存放监听器。但是它并不是直接存放，而是先存监听器的class类型，然后再存监听器本身。即存放(MyListener.class , myListener)。一个Object数组可以存放多种类型的Listener，如果还有一种监听器AnotherListener，那么(AnotherListener.class , anotherListener)也可以存放。无论增删都是两个对象一同被添加或删除。上述代码中的listenerList.add(MyListener.class , listener)或listenerList.remove(MyListener.class , listener)，以及fireDoMyAction()中的"i-=2"，就是这样操作的。</strong>
						<br />
				</p>
		</dd>
<img src ="http://www.blogjava.net/kyleYang/aggbug/309871.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kyleYang/" target="_blank">飞熊</a> 2010-01-17 18:15 <a href="http://www.blogjava.net/kyleYang/archive/2010/01/17/309871.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>适配器Adapter</title><link>http://www.blogjava.net/kyleYang/archive/2010/01/17/309869.html</link><dc:creator>飞熊</dc:creator><author>飞熊</author><pubDate>Sun, 17 Jan 2010 09:54:00 GMT</pubDate><guid>http://www.blogjava.net/kyleYang/archive/2010/01/17/309869.html</guid><wfw:comment>http://www.blogjava.net/kyleYang/comments/309869.html</wfw:comment><comments>http://www.blogjava.net/kyleYang/archive/2010/01/17/309869.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kyleYang/comments/commentRss/309869.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kyleYang/services/trackbacks/309869.html</trackback:ping><description><![CDATA[
		<p>
				<font style="BACKGROUND-COLOR: #cce8cf">1.意图:<br />            将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原来由于版本不兼容而不能在一起的够哦那个做的那些类可以在一起工作。有时，为复用而设计的工具箱类不能够被复用的原因仅仅是因为它的接口与专业应用领域所需要的接口不匹配。<br />2.适配器模式有类的适配器模式和对象的适配器模式两种不同的形式。<br /><br />一、类的适配器模式<br />    类的适配器模式把适配的类的API转换成目标类的API。 <br /></font>
		</p>
		<ul>
				<li>目标(Target)角色：这就是所期待得到的接口。 <br /></li>
		</ul>
		<ul>
				<li>源(Adaptee)角色：现有需要适配的接口。 <br /></li>
				<li>适配器(Adapter)角色：适配器类是本模式的核心。适配器把源接口转换成目标接口。显然这一角色不可以是接口，而必须是具体类。 </li>
		</ul>
		<p>/**<br /> * 定义Client使用的与特定领域相关的接口<br /> */<br />public interface Target {<br />    void sampleOperation1();<br />    void sampleOperation2();<br />}<br />/**<br /> * 定义一个已经存在的接口，这个接口需要适配<br /> */<br />public class Adaptee {<br />    public void sampleOperation1() {<br />        // ......<br />    }<br />}<br />/**<br /> * 对Adaptee与Target接口进行适配<br /> */<br />public class Adapter extends Adaptee implements Target {<br />    public void sampleOperation2() {<br />        // ......<br />    }<br />}<br /><br />二、对象适配器<br />    与类的适配器模式一样，对象适配器模式把适配的类的API转换成为目标类的API，与类的适配器模式不同的是，对象的适配器模式不是使用继承关系连接到Adaptee类，而是使用委派关系连接到Adaptee类。示意代码如下：<br />/**<br /> * 定义Client使用的与特定领域相关的接口<br /> */<br />public interface Target {<br />    void sampleOperation1();<br />    void sampleOperation2();<br />}<br />/**<br /> * 定义一个已经存在的接口，这个接口需要适配<br /> */<br />public class Adaptee {<br />    public void sampleOperation1() {<br />        // ......<br />    }<br />}<br />/**<br /> * 对Adaptee与Target接口进行适配<br /> */<br />public class Adapter implements Target {<br />    private Adaptee adaptee;<br />    public Adapter(Adaptee adaptee) {<br />        super();<br />        this.adaptee = adaptee;<br />    }<br />    public void sampleOperation1() {<br />        adaptee.sampleOperation1(); // 看点<br />    }<br />    public void sampleOperation2() {<br />        // ......<br />    }<br />}<br /><br />类适配器模式和对象适配器模式的异同：Target接口和Adaptee类都相同，不同的是类适配器的Adapter继承Adaptee实现Target，对象适配器的Adapter实现Target聚集Adaptee。<br /><br />适配器模式的用意是将接口不同而功能相同或者相近的两个接口加以转换。<br /></p>
<img src ="http://www.blogjava.net/kyleYang/aggbug/309869.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kyleYang/" target="_blank">飞熊</a> 2010-01-17 17:54 <a href="http://www.blogjava.net/kyleYang/archive/2010/01/17/309869.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>迭代器模式</title><link>http://www.blogjava.net/kyleYang/archive/2010/01/17/309868.html</link><dc:creator>飞熊</dc:creator><author>飞熊</author><pubDate>Sun, 17 Jan 2010 09:53:00 GMT</pubDate><guid>http://www.blogjava.net/kyleYang/archive/2010/01/17/309868.html</guid><wfw:comment>http://www.blogjava.net/kyleYang/comments/309868.html</wfw:comment><comments>http://www.blogjava.net/kyleYang/archive/2010/01/17/309868.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kyleYang/comments/commentRss/309868.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kyleYang/services/trackbacks/309868.html</trackback:ping><description><![CDATA[aa<img src ="http://www.blogjava.net/kyleYang/aggbug/309868.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kyleYang/" target="_blank">飞熊</a> 2010-01-17 17:53 <a href="http://www.blogjava.net/kyleYang/archive/2010/01/17/309868.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java代理模式及动态代理类</title><link>http://www.blogjava.net/kyleYang/archive/2010/01/17/309860.html</link><dc:creator>飞熊</dc:creator><author>飞熊</author><pubDate>Sun, 17 Jan 2010 08:52:00 GMT</pubDate><guid>http://www.blogjava.net/kyleYang/archive/2010/01/17/309860.html</guid><wfw:comment>http://www.blogjava.net/kyleYang/comments/309860.html</wfw:comment><comments>http://www.blogjava.net/kyleYang/archive/2010/01/17/309860.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kyleYang/comments/commentRss/309860.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kyleYang/services/trackbacks/309860.html</trackback:ping><description><![CDATA[
		<p class="MsoNormal" style="MARGIN-LEFT: 18pt; TEXT-INDENT: -18pt">
				<strong>
						<span lang="EN-US">1.</span>
				</strong>
				<span lang="EN-US" style="FONT-SIZE: 7pt; FONT-FAMILY: 'Times New Roman','serif'">      </span>
				<strong>
						<span style="FONT-FAMILY: 宋体">代理模式</span>
						<span lang="EN-US">
								<?XML:NAMESPACE PREFIX = O /?>
								<o:p>
								</o:p>
						</span>
				</strong>
		</p>
		<p class="MsoNormal" style="MARGIN-LEFT: 21pt; TEXT-INDENT: 21pt">
				<span style="FONT-FAMILY: 宋体">代理模式的作用是：为其他对象提供一种代理以控制对这个对象的访问。在某些情况下，一个客户不想或者不能直接引用另一个对象，而代理对象可以在客户端和目标对象之间起到中介的作用。</span>
		</p>
		<p class="MsoNormal" style="MARGIN-LEFT: 21pt; TEXT-INDENT: 21pt">
				<span style="FONT-FAMILY: 宋体">代理模式一般涉及到的角色有：</span>
		</p>
		<p class="MsoNormal">
				<strong>
						<span style="FONT-FAMILY: 宋体">抽象角色</span>
				</strong>
				<span style="FONT-FAMILY: 宋体">：声明真实对象和代理对象的共同接口；</span>
		</p>
		<p class="MsoNormal">
				<strong>
						<span style="FONT-FAMILY: 宋体">代理角色</span>
				</strong>
				<span style="FONT-FAMILY: 宋体">：代理对象角色内部含有对真实对象的引用，从而可以操作真实对象，同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时，代理对象可以在执行真实对象操作时，附加其他的操作，相当于对真实对象进行封装。</span>
		</p>
		<p class="MsoNormal">
				<strong>
						<span style="FONT-FAMILY: 宋体">真实角色</span>
				</strong>
				<span style="FONT-FAMILY: 宋体">：代理角色所代表的真实对象，是我们最终要引用的对象。</span>
				<span lang="EN-US">(</span>
				<span style="FONT-FAMILY: 宋体">参见文献</span>
				<span lang="EN-US">1)</span>
		</p>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体">以下以《</span>
				<span lang="EN-US">Java</span>
				<span style="FONT-FAMILY: 宋体">与模式》中的示例为例：</span>
		</p>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体">抽象角色：</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">abstract public class Subject</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">{</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">    abstract public void request();</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">}</span>
		</p>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体">真实角色：实现了</span>
				<span lang="EN-US">Subject</span>
				<span style="FONT-FAMILY: 宋体">的</span>
				<span lang="EN-US">request()</span>
				<span style="FONT-FAMILY: 宋体">方法。</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">public class RealSubject extends Subject </span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">{</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">       public RealSubject()</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">       { </span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">       }</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">       </span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">       public void request()</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">       { </span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">              System.out.println("From real subject.");</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">       }</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">}</span>
		</p>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体">代理角色：</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">public class ProxySubject extends Subject </span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">{</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">    private RealSubject realSubject;  //</span>
				<span style="FONT-FAMILY: 宋体">以真实角色作为代理角色的属性</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">       </span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">       public ProxySubject()</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">       {</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">       }</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
				</span> </p>
		<p class="MsoNormal">
				<span lang="EN-US">       public void request()  //</span>
				<span style="FONT-FAMILY: 宋体">该方法封装了真实对象的</span>
				<span lang="EN-US">request</span>
				<span style="FONT-FAMILY: 宋体">方法</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">       {</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">        preRequest();  </span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">              if( realSubject == null )</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">        {</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">                     realSubject = new RealSubject();</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">              }</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">        realSubject.request();  //</span>
				<span style="FONT-FAMILY: 宋体">此处执行真实对象的</span>
				<span lang="EN-US">request</span>
				<span style="FONT-FAMILY: 宋体">方法</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">        postRequest(); </span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">       }</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
				</span> </p>
		<p class="MsoNormal">
				<span lang="EN-US">    private void preRequest()</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">    {</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">        //something you want to do before requesting</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">    }</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
				</span> </p>
		<p class="MsoNormal">
				<span lang="EN-US">    private void postRequest()</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">    {</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">        //something you want to do after requesting</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">    }</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">}</span>
		</p>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体">客户端调用：</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">Subject sub=new ProxySubject();</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">Sub.request();</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">       </span>
				<span style="FONT-FAMILY: 宋体">由以上代码可以看出，客户实际需要调用的是</span>
				<span lang="EN-US">RealSubject</span>
				<span style="FONT-FAMILY: 宋体">类的</span>
				<span lang="EN-US">request()</span>
				<span style="FONT-FAMILY: 宋体">方法，现在用</span>
				<span lang="EN-US">ProxySubject</span>
				<span style="FONT-FAMILY: 宋体">来代理</span>
				<span lang="EN-US">RealSubject</span>
				<span style="FONT-FAMILY: 宋体">类，同样达到目的，同时还封装了其他方法</span>
				<span lang="EN-US">(preRequest(),postRequest())</span>
				<span style="FONT-FAMILY: 宋体">，可以处理一些其他问题。</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">       </span>
				<span style="FONT-FAMILY: 宋体">另外，如果要按照上述的方法使用代理模式，那么真实角色必须是事先已经存在的，并将其作为代理对象的内部属性。但是实际使用时，一个真实角色必须对应一个代理角色，如果大量使用会导致类的急剧膨胀；此外，如果事先并不知道真实角色，该如何使用代理呢？这个问题可以通过</span>
				<span lang="EN-US">Java</span>
				<span style="FONT-FAMILY: 宋体">的动态代理类来解决。</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
				</span> </p>
		<p class="MsoNormal">
				<strong>
						<span lang="EN-US">2.</span>
				</strong>
				<strong>
						<span style="FONT-FAMILY: 宋体">动态代理类</span>
				</strong>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">       Java</span>
				<span style="FONT-FAMILY: 宋体">动态代理类位于</span>
				<span lang="EN-US">Java.lang.reflect</span>
				<span style="FONT-FAMILY: 宋体">包下，一般主要涉及到以下两个类：</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">(1). Interface InvocationHandler</span>
				<span style="FONT-FAMILY: 宋体">：该接口中仅定义了一个方法</span>
				<span lang="EN-US">Object</span>
				<span style="FONT-FAMILY: 宋体">：</span>
				<span lang="EN-US">invoke(Object obj,Method method, <span><span class="MsoHyperlink">Object</span></span>[] args)</span>
				<span style="FONT-FAMILY: 宋体">。在实际使用时，第一个参数</span>
				<span lang="EN-US">obj</span>
				<span style="FONT-FAMILY: 宋体">一般是指代理类，</span>
				<span lang="EN-US">method</span>
				<span style="FONT-FAMILY: 宋体">是被代理的方法，如上例中的</span>
				<span lang="EN-US">request()</span>
				<span style="FONT-FAMILY: 宋体">，</span>
				<span lang="EN-US">args</span>
				<span style="FONT-FAMILY: 宋体">为该方法的参数数组。这个抽象方法在代理类中动态实现。</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<br />(2).Proxy</span>
				<span style="FONT-FAMILY: 宋体">：该类即为动态代理类，作用类似于上例中的</span>
				<span lang="EN-US">ProxySubject</span>
				<span style="FONT-FAMILY: 宋体">，其中主要包含以下内容：</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">Protected Proxy(InvocationHandler h)</span>
				<span style="FONT-FAMILY: 宋体">：构造函数，估计用于给内部的</span>
				<span lang="EN-US">h</span>
				<span style="FONT-FAMILY: 宋体">赋值。</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">Static Class getProxyClass (ClassLoader loader, Class[] interfaces)</span>
				<span style="FONT-FAMILY: 宋体">：获得一个代理类，其中</span>
				<span lang="EN-US">loader</span>
				<span style="FONT-FAMILY: 宋体">是类装载器，</span>
				<span lang="EN-US">interfaces</span>
				<span style="FONT-FAMILY: 宋体">是真实类所拥有的全部接口的数组。</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">Static Object <a href="/cooperlee321/archive/2010/01/03/308109.html#newProxyInstance%28java.lang.ClassLoader,%20java.lang.Class[],%20java.lang.reflect.InvocationHandler%29">newProxyInstance</a>(ClassLoader loader, Class[] interfaces, InvocationHandler h)</span>
				<span style="FONT-FAMILY: 宋体">：返回代理类的一个实例，返回后的代理类可以当作被代理类使用</span>
				<span lang="EN-US">(</span>
				<span style="FONT-FAMILY: 宋体">可使用被代理类的在</span>
				<span lang="EN-US">Subject</span>
				<span style="FONT-FAMILY: 宋体">接口中声明过的方法</span>
				<span lang="EN-US">)</span>
				<span style="FONT-FAMILY: 宋体">。</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<br />       </span>
				<span style="FONT-FAMILY: 宋体">所谓</span>
				<span lang="EN-US">Dynamic Proxy</span>
				<span style="FONT-FAMILY: 宋体">是这样一种</span>
				<span lang="EN-US">class</span>
				<span style="FONT-FAMILY: 宋体">：它是在运行时生成的</span>
				<span lang="EN-US">class</span>
				<span style="FONT-FAMILY: 宋体">，在生成它时你必须提供一组</span>
				<span lang="EN-US">interface</span>
				<span style="FONT-FAMILY: 宋体">给它，然后该</span>
				<span lang="EN-US">class</span>
				<span style="FONT-FAMILY: 宋体">就宣称它实现了这些</span>
				<span lang="EN-US"> interface</span>
				<span style="FONT-FAMILY: 宋体">。你当然可以把该</span>
				<span lang="EN-US">class</span>
				<span style="FONT-FAMILY: 宋体">的实例当作这些</span>
				<span lang="EN-US">interface</span>
				<span style="FONT-FAMILY: 宋体">中的任何一个来用。当然啦，这个</span>
				<span lang="EN-US">Dynamic Proxy</span>
				<span style="FONT-FAMILY: 宋体">其实就是一个</span>
				<span lang="EN-US">Proxy</span>
				<span style="FONT-FAMILY: 宋体">，它不会替你作实质性的工作，在生成它的实例时你必须提供一个</span>
				<span lang="EN-US">handler</span>
				<span style="FONT-FAMILY: 宋体">，由它接管实际的工作。</span>
				<span lang="EN-US">(</span>
				<span style="FONT-FAMILY: 宋体">参见文献</span>
				<span lang="EN-US">3)</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">    </span>
				<span style="FONT-FAMILY: 宋体">在使用动态代理类时，我们必须实现</span>
				<span lang="EN-US">InvocationHandler</span>
				<span style="FONT-FAMILY: 宋体">接口，以第一节中的示例为例：</span>
		</p>
		<p class="MsoNormal">
				<strong>
						<span style="FONT-FAMILY: 宋体">抽象角色</span>
				</strong>
				<span lang="EN-US">(</span>
				<span style="FONT-FAMILY: 宋体">之前是抽象类，此处应改为接口</span>
				<span lang="EN-US">)</span>
				<span style="FONT-FAMILY: 宋体">：</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">public interface Subject</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">{</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">    abstract public void request();</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">}</span>
		</p>
		<p class="MsoNormal">
				<strong>
						<span style="FONT-FAMILY: 宋体">具体角色</span>
				</strong>
				<span lang="EN-US">RealSubject</span>
				<span style="FONT-FAMILY: 宋体">：同上；</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
				</span> </p>
		<p class="MsoNormal">
				<strong>
						<span style="FONT-FAMILY: 宋体">代理角色：</span>
						<span lang="EN-US">
								<o:p>
								</o:p>
						</span>
				</strong>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">import java.lang.reflect.Method;</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">import java.lang.reflect.InvocationHandler;</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
				</span> </p>
		<p class="MsoNormal">
				<span lang="EN-US">public class DynamicSubject implements InvocationHandler {</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">  private Object sub;</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
				</span> </p>
		<p class="MsoNormal">
				<span lang="EN-US">  public DynamicSubject() {</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">  }</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
				</span> </p>
		<p class="MsoNormal">
				<span lang="EN-US">  public DynamicSubject(Object obj) {</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">    sub = obj;</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">  }</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
				</span> </p>
		<p class="MsoNormal">
				<span lang="EN-US">
				</span> </p>
		<p class="MsoNormal">
				<span lang="EN-US">  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">    System.out.println("before calling " + method);</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
				</span> </p>
		<p class="MsoNormal">
				<span lang="EN-US">    method.invoke(sub,args);</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
				</span> </p>
		<p class="MsoNormal">
				<span lang="EN-US">    System.out.println("after calling " + method);</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">    return null;</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">  }</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
				</span> </p>
		<p class="MsoNormal">
				<span lang="EN-US">}</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
				</span> </p>
		<p class="MsoNormal">
				<span lang="EN-US">       </span>
				<span style="FONT-FAMILY: 宋体">该代理类的内部属性为</span>
				<span lang="EN-US">Object</span>
				<span style="FONT-FAMILY: 宋体">类，实际使用时通过该类的构造函数</span>
				<span lang="EN-US">DynamicSubject(Object obj)</span>
				<span style="FONT-FAMILY: 宋体">对其赋值；此外，在该类还实现了</span>
				<span lang="EN-US">invoke</span>
				<span style="FONT-FAMILY: 宋体">方法，该方法中的</span>
		</p>
		<p class="MsoNormal" style="TEXT-INDENT: 21pt">
				<span lang="EN-US">method.invoke(sub,args);</span>
		</p>
		<p class="MsoNormal">
				<span style="FONT-FAMILY: 宋体">其实就是调用被代理对象的将要被执行的方法，方法参数</span>
				<span lang="EN-US">sub</span>
				<span style="FONT-FAMILY: 宋体">是实际的被代理对象，</span>
				<span lang="EN-US">args</span>
				<span style="FONT-FAMILY: 宋体">为执行被代理对象相应操作所需的参数。通过动态代理类，我们可以在调用之前或之后执行一些相关操作。</span>
		</p>
		<p class="MsoNormal">
				<strong>
						<span style="FONT-FAMILY: 宋体">客户端</span>
				</strong>
				<span style="FONT-FAMILY: 宋体">：</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">import java.lang.reflect.InvocationHandler;</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">import java.lang.reflect.Proxy;</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">import java.lang.reflect.Constructor;</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">import java.lang.reflect.Method;</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
				</span> </p>
		<p class="MsoNormal">
				<span lang="EN-US">public class Client</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">{</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
				</span> </p>
		<p class="MsoNormal">
				<span lang="EN-US">    static public void main(String[] args) throws Throwable</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">       {</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">      RealSubject rs = new RealSubject();  //</span>
				<span style="FONT-FAMILY: 宋体">在这里指定被代理类</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">      InvocationHandler ds = new DynamicSubject(rs);  //</span>
				<span style="FONT-FAMILY: 宋体">初始化代理类</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">         Class cls = rs.getClass();</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">      //</span>
				<span style="FONT-FAMILY: 宋体">以下是分解步骤</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">      /*</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">      Class c = Proxy.getProxyClass(cls.getClassLoader(),cls.getInterfaces()) ;</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">      Constructor ct=c.getConstructor(new Class[]{InvocationHandler.class});</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">      Subject subject =(Subject) ct.newInstance(new Object[]{ds});</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">     */</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">     //</span>
				<span style="FONT-FAMILY: 宋体">以下是一次性生成</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">      Subject subject = (Subject) Proxy.newProxyInstance(cls.getClassLoader(),</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">                                 cls.getInterfaces(),ds );</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">
						<br />      subject.request();</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">}</span>
		</p>
		<p class="MsoNormal">
				<span lang="EN-US">       </span>
				<span style="FONT-FAMILY: 宋体">通过这种方式，被代理的对象</span>
				<span lang="EN-US">(RealSubject)</span>
				<span style="FONT-FAMILY: 宋体">可以在运行时动态改变，需要控制的接口</span>
				<span lang="EN-US">(Subject</span>
				<span style="FONT-FAMILY: 宋体">接口</span>
				<span lang="EN-US">)</span>
				<span style="FONT-FAMILY: 宋体">可以在运行时改变，控制的方式</span>
				<span lang="EN-US">(DynamicSubject</span>
				<span style="FONT-FAMILY: 宋体">类</span>
				<span lang="EN-US">)</span>
				<span style="FONT-FAMILY: 宋体">也可以动态改变，从而实现了非常灵活的动态代理关系</span>
				<span lang="EN-US">(</span>
				<span style="FONT-FAMILY: 宋体">参见文献</span>
				<span lang="EN-US">2)</span>
				<span style="FONT-FAMILY: 宋体">。</span>
		</p>
<img src ="http://www.blogjava.net/kyleYang/aggbug/309860.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kyleYang/" target="_blank">飞熊</a> 2010-01-17 16:52 <a href="http://www.blogjava.net/kyleYang/archive/2010/01/17/309860.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>单例模式</title><link>http://www.blogjava.net/kyleYang/archive/2010/01/14/309585.html</link><dc:creator>飞熊</dc:creator><author>飞熊</author><pubDate>Thu, 14 Jan 2010 14:55:00 GMT</pubDate><guid>http://www.blogjava.net/kyleYang/archive/2010/01/14/309585.html</guid><wfw:comment>http://www.blogjava.net/kyleYang/comments/309585.html</wfw:comment><comments>http://www.blogjava.net/kyleYang/archive/2010/01/14/309585.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/kyleYang/comments/commentRss/309585.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/kyleYang/services/trackbacks/309585.html</trackback:ping><description><![CDATA[
		<p>1.饿汉式单例类<br />public class Singleton {</p>
		<p>　　private Singleton(){}</p>
		<p>　　//在自己内部定义自己一个实例，是不是很奇怪？<br />　　//注意这是private 只供内部调用</p>
		<p>　　private static Singleton instance = new Singleton();</p>
		<p>　　//这里提供了一个供外部访问本class的静态方法，可以直接访问　　<br />　　public static Singleton getInstance() {<br />　　　　return instance; 　　<br />　　 } <br />}</p>
		<p>2.懒汉式单例类<br /><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> Singleton2 {<br />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">私有的默认构造子</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> Singleton2() {}<br />    <br />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">注意，这里没有final    </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> Singleton2 single;<br />    <br />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">只实例化一次</span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">{<br />        single </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> Singleton2();<br />    }<br />    <br />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">静态工厂方法 </span><span style="COLOR: #008000"><br /></span><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">synchronized</span><span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> Singleton2 getInstance() {<br />         </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (single </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">) {  <br />             single </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> Singleton2();<br />         }  <br />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> single;<br />    }<br />}<br /></span>        上面给出懒汉式单例类实现里对静态工厂方法使用了同步化，以处理多线程环境。有些设计师在这里建议使用所谓的"双重检查成例".必须指出的是，"双重检查成例"不可以在Java 语言中使用。不十分熟悉的读者，可以看看后面给出的小节。 同样，由于构造子是私有的，因此，此类不能被继承。饿汉式单例类在自己被加载时就将自己实例化。即便加载器是静态的，在饿汉式单例类被加载时仍会将自己实例化。单从资源利用效率角度来讲，这个比懒汉式单例类稍差些。从速度和反应时间角度来讲，则比懒汉式单例类稍好些。然而，懒汉式单例类在实例化时，必须处理好在多个线程同时首次引用此类时的访问限制问题，特别是当单例类作为资源控制器，在实例化时必然涉及资源初始化，而资源初始化很有可能耗费时间。这意味着出现多线程同时首次引用此类的机率变得较大。<br /><br />3.单例模式 -- 双重检查锁机制<br /><span style="COLOR: rgb(0,0,255)">public</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">class</span><span style="COLOR: rgb(0,0,0)"> DoubleLockSingleton {<br /></span> <span style="COLOR: rgb(0,0,255)">   private</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">static</span><span style="COLOR: rgb(0,0,0)"> DoubleLockSingleton instance </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">null</span><span style="COLOR: rgb(0,0,0)">;<br /></span><span style="COLOR: rgb(0,0,255)">    private</span><span style="COLOR: rgb(0,0,0)"> DoubleLockSingleton() {<br /></span><span style="COLOR: rgb(0,128,128)">    </span><span style="COLOR: rgb(0,0,0)">}<br /></span><br />    <font color="#0000ff">public </font>static DoubleLockSingleton getInstance()<br />   {<br />     if (instance == null)<br />     {<br />       synchronized(DoubleLockSingleton .class) {  //1<br />         if (instance == null)          //2<br />           instance = new DoubleLockSingleton ();  //3<br />       }<br />     }<br />     return instance;<br />   }<br />}<br />Singleton的好处还在于可以节省内存，因为它限制了<br />实例的个数，有利于Java垃圾回收（garbage collection）。<br /> <br />4.发明者是Google公司的Bob lee:<br /> public   class  Singleton   {   <br />  <br />   static   class  SingletonHolder   {   <br />     static  Singleton instance  =   new  Singleton();   <br />  }    <br />  <br />   public   static  Singleton getInstance()   {   <br />     return  SingletonHolder.instance;   <br />  }    <br />  <br />} </p>
<img src ="http://www.blogjava.net/kyleYang/aggbug/309585.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/kyleYang/" target="_blank">飞熊</a> 2010-01-14 22:55 <a href="http://www.blogjava.net/kyleYang/archive/2010/01/14/309585.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>