<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>聪明的笨蛋</title>
    <description>做喜欢的事，追喜欢的女孩。</description>
    <link>http://smartfool.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>Oracle创建表空间</title>
        <author>lintomny</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://smartfool.javaeye.com">lintomny</a>&nbsp;
          链接：<a href="http://smartfool.javaeye.com/blog/234183" style="color:red;">http://smartfool.javaeye.com/blog/234183</a>&nbsp;
          发表时间: 2008年08月28日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="sql">--创建临时表空间
CREATE TEMPORARY TABLESPACE TS_TMP 
TEMPFILE 'D:\ORACLE\ORADATA\TMP\TMP.DBF' 
SIZE 32M 
AUTOEXTEND ON 
NEXT 32M MAXSIZE 2048M
EXTENT MANAGEMENT LOCAL;


--创建数据表空间
CREATE TABLESPACE TS_DATA
LOGGING
DATAFILE 'D:\ORACLE\ORADATA\TMP\DATA.DBF' 
SIZE 32M 
AUTOEXTEND ON 
NEXT 32M MAXSIZE 2048M
EXTENT MANAGEMENT LOCAL;

--创建用户并指定表空间
CREATE USER db IDENTIFIED BY db
DEFAULT TABLESPACE TS_DATA
TEMPORARY TABLESPACE TS_TMP;

--给用户授予权限
GRANT CONNECT, RESOURCE TO db;</pre>
&nbsp;
          <br/><br/>
          <span style="color:red;">
            <a href="http://smartfool.javaeye.com/blog/234183#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 28 Aug 2008 22:13:08 +0800</pubDate>
        <link>http://smartfool.javaeye.com/blog/234183</link>
        <guid>http://smartfool.javaeye.com/blog/234183</guid>
      </item>
      <item>
        <title>[翻译]需求的用例文档管理</title>
        <author>lintomny</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://smartfool.javaeye.com">lintomny</a>&nbsp;
          链接：<a href="http://smartfool.javaeye.com/blog/211872" style="color:red;">http://smartfool.javaeye.com/blog/211872</a>&nbsp;
          发表时间: 2008年07月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>原文：<a href="http://searchsoftwarequality.techtarget.com/expert/KnowledgebaseAnswer/0,289625,sid92_gci1315460_tax306118,00.html" target="_blank">http://searchsoftwarequality.techtarget.com/expert/KnowledgebaseAnswer/0,289625,sid92_gci1315460_tax306118,00.html</a>
 </p>
<p>&nbsp;</p>
<p><strong><span style="font-size: medium;">问题</span>
 ：</strong>
</p>
<p>我需要为一个现存的应用系统建立一些用例。这个系统有大量的相关文档，其中一些已经规格化了，同时也仍有好些没有整理。那如何通过用例来描述这种状态比较好呢？</p>
<p>&nbsp;</p>
<p><span style="font-size: medium;"><strong>专家回答：</strong>
</span>
 </p>
<p>很好的问题。不管是新建的还是现存的，各式文档对于许多的应用系统来说都是十分重要的。</p>
<p>&nbsp;</p>
<p>首先，来考虑一下文档到底是什么，而用例又用来做什么的。文档是一种信息的集合，这些信息能够被分割、组织以及以各种不同的方式进行传递（打印成册或网络等等）。用例是一项简单但却强大的技术，它揭示了用户需要完成的工作（当然，是在应用系统的帮助下）。这样，一个用例标识了一个用户的任务&mdash;&mdash;如&ldquo;检视客户信息&rdquo;&mdash;&mdash;经过整理最终形成文件或者网络文档。</p>
<p>&nbsp;</p>
<p>虽然我是用例技术的大粉丝，因为它关注用户，但有效的需求定义需要有更多的手段。在一个用户需求如&ldquo;检视用户信息&rdquo;（一个用例）中包含有大量的我们并不容易捕获的信息。你必须把这些信息作为某个特定信息集合的元数据来思考。比如说，你可能需要整理出一份文档的定义，提供者和接收者，传阅频度，（传阅）时机，（传阅）条件，以及其他的一开始就需要确定的东西。</p>
<p>&nbsp;</p>
<p>整理这些附加的文档信息并不等于将用例技术束之高阁，它实际上是在强调单纯地描述用户任务&ldquo;监视客户信息&rdquo;是不够的。一个常见的编制文档的方式是创建一份用于整理这些描述的信息的文档定义模板。但这种方法并不包治百病，它不能帮助我们从一堆文档中找出缺失或相互矛盾的信息，或者找出有助于文档统一的模式。首先，我来跟大家分享我使用的两种技术：文档用例模式以及文档定义列表。在概述中，我会使用这两项技术来回答上面的问题。</p>
<p>&nbsp;</p>
<p><strong><span style="font-size: small;">用例文档样本</span>
 </strong>
</p>
<p>我常常在寻找样本模式&mdash;&mdash;词组模式、处理步骤模式等等。同时，我也发现一份文档实际上是一组_______的信息集合（根据实际情况进行填空），我也发现当用户要求&ldquo;监视_______的信息&rdquo;包含着一些特殊的处理步骤。这个会让你发出&ldquo;啊~哈&rdquo;的发现告诉我是时候为这些&ldquo;监视_______的信息&rdquo;的用例定义样本模式了。我发现这样本模式很简单，然而之前要我整理所有的信息之间的关系却让我心有余悸。（事后也往往证明，整理出来的这些所有文档间关系并不都是有用的。）记住，下面所说的样本只是一个开端，它将为用户任务的处理步骤的整理带来简易与一致。</p>
<p>&nbsp;</p>
<p><img src="http://lh4.ggpht.com/lintomny/SHFIV1lTVWI/AAAAAAAABtU/3aAKnfsIfc4/s800/2023242132596244351.jpg" alt="" />
</p>
<p>&nbsp;</p>
<p><span style="font-size: small;"><strong>文档定义列表</strong>
</span>
</p>
<p>下面的文档定义列表是经过若干次文档讨论后得出的。你或许会发现在这里样例中，文档的信息在Excel电子表格中被进行了分类，并合拢了一些列。如果你手头上有其他（比Excel）更好的处理工具你也可以拿来使用，不过这种信息分组的原则还是适用的。&nbsp;</p>
<p>&nbsp;</p>
<p>花一点时间来粗略看看文档中的各项信息的标识吧。</p>
<p>&nbsp;</p>
<p><img src="http://lh4.ggpht.com/lintomny/SHFIVxpP1nI/AAAAAAAABtc/QyQjVnL7Cxo/s800/3015441425501300523.jpg" alt="" />
</p>
<p>&nbsp;</p>
<p>现在，我们来展开样例中的各项分组。你应该会发现DEFINITION和PROVIDER-RECEIVER分组中几个信息列都填上了适当的内容。</p>
<p>&nbsp;</p>
<p><img src="http://lh3.ggpht.com/lintomny/SHFIV25i_uI/AAAAAAAABtk/eVoDGc8y_Ug/s800/3023885674802708084.jpg" alt="" />
</p>
<p>&nbsp;</p>
<p>注意：在CONTENT栏中有有些信息只是写了引用（自哪份文档），这是因为已经有人做了一份文档（Report Data Definition）对这些数据进行规格化了。他们也不需知道谁将要看这些文档。同样地注意一下DELIVERY的组织方式。</p>
<p>&nbsp;</p>
<p><img src="http://lh5.ggpht.com/lintomny/SHFIWL030AI/AAAAAAAABts/8PqZvtoyhl4/s800/3023885674802708092.jpg" alt="" />
</p>
<p>&nbsp;</p>
<p>在FORMAT和CRITERIA栏中，有些列会来回叙述&ldquo;是什么&rdquo;及&ldquo;如何&rdquo;。当定义一个新的文档时，需求应该遵循某种公认的标准来撰写，但当这些需求是不言自明的时候是不需要规格化的。当你整理一份文档时，你拿到了这些（不言自明的）信息，那问一下自己详细叙述这些信息是否有用。如果确实有用，那就记录下来并对之进行组织整理。此外，还要注意CRITERIA栏的信息，如条件(filter)和分类(sort)，注明引用了用例文档样本中的哪些样本。</p>
<p>&nbsp;</p>
<p><img src="http://lh5.ggpht.com/lintomny/SHFIWAd71lI/AAAAAAAABt0/Q4Pv4qlK6Ks/s800/3023885674802708094.jpg" alt="" />
</p>
<p>&nbsp;</p>
<p><span style="font-size: small;"><strong>小结</strong>
</span>
</p>
<p>最后，我建议你把目光放得更远些而不要囿于你手头上的工作，因为你要使你正在创建的文档有用。了解这份文档是如何使用，这毫无疑问是让你真正掌握它的各种潜在用处的不二之法。显然，这份文档不是用于开发一个新应用系统的，它是已经存在的。尽管如此，还是有一些潜在的应用价值可以利用这些用例及其相关的文档的，它们是：</p>
<ul>
<li>撰写用户指南</li>
<li>培训新员工</li>
<li>回归测试依据</li>
<li>应用系统替换的需求</li>
</ul>
<p>上述各项，整理&ldquo;是什么&rdquo;是必须要做的，而整理&ldquo;如何&rdquo;则可据情况而定（参考上面样例中的FORMAT栏）。如果你正在整理的需求（同时又是你在整理用例时需要整理的）是用于应用系统替换的，那么一些关于&ldquo;如何&rdquo;替换的并非必要的限制的论述是可以加上去的。</p>
<p>&nbsp;</p>
<p>以上原则了然于心后，来考虑一下下面的这个文档整理方法：</p>
<ul>
<li>粗略浏览一下文档定义列表，删除并不适用的描述，同时完善那些在你看来并不太准确的描述。</li>
<li>在文档定义列表中填上你手头的每一份文档，并用这个列表来作为指南来提问题。对于那些没有规格化的文档，在假设这些文档存在的基础上思考并给出可以找到关于这份文档的更多信息的引用索引。</li>
<li>为用例&ldquo;检视_______信息&rdquo;的用例命名。在你为每一份用例文档命名前，看看是否在文档定义列表中已有相关的文档信息。</li>
<li>如果能找到，填上&ldquo;检视_______信息&rdquo;用例文档，同时要记得要在文档定义列表中为此用例加上引用。</li>
<li>如果找不到，就在用例样本和文档定义列表中填上所有的关于用户任何及文档元数据的相关必要信息。</li>
</ul>
<p>不管找到与否，信息都应当避免重复冗余，达到一处描述多处引用。</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://smartfool.javaeye.com/blog/211872#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 05 Jul 2008 16:06:12 +0800</pubDate>
        <link>http://smartfool.javaeye.com/blog/211872</link>
        <guid>http://smartfool.javaeye.com/blog/211872</guid>
      </item>
      <item>
        <title>Visitor - 访问者模式</title>
        <author>lintomny</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://smartfool.javaeye.com">lintomny</a>&nbsp;
          链接：<a href="http://smartfool.javaeye.com/blog/207092" style="color:red;">http://smartfool.javaeye.com/blog/207092</a>&nbsp;
          发表时间: 2008年06月23日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>话说有一个银行，有三个窗口，但是每个窗口的智能都是一样的，即都能办理所有的业务。因此每位来银行办理业务的人只要排队就是了，排到你了，就向业务员说明你要办理的业务，然后业务员根据你的业务选择不同的单据，打开不同的账本。&hellip;&hellip;。</p>
<p>&nbsp;</p>
<p>业务员此时典型的工作流程是：</p>
<pre name="code" class="java">if (service instanceof Saving){
    //存款
   ......
}else if (service instanceof Draw){
    //提款
   ......
}else if (service instanceof Fund){
    //基金
   ......
} 
......</pre>
&nbsp;
<p>于是每位业务员的桌面总是塞得满满的，更重要的是大量的时间都花在受理不同业务之间的切换，使得效率很低。</p>
<p>&nbsp;</p>
<p>有没有方法能够使得业务员的工作效率提高呢？银行经理苦思冥想了半天，终于想出了一个好办法。他让每个窗口各负责一个业务，同时委任了一位访问者(Visitor)，负责在客户进门时，询问他要办理什么业务，告诉他应该去哪个窗口办理。这样，每个窗口的业务员就只负责一项业务，<span style="color: #ff0000;"><strong>减少了在不同业务间切换的时间耗费</strong>
</span>
，效率大大提高。更重要的是，<span style="color: #ff0000;"><strong>当某一项业务的处理流程发生变更时，不需要同时麻烦三个窗口的业务员，而只需要让处理这项业务的业务员进行修改就可以了</strong>
</span>
。</p>
<p>&nbsp;</p>
<p>下面就来定义Visitor类，这个Visitor类实际上还办含了不同窗口受理员的职责，可以认为是银行的受理反应机制吧。</p>
<p>&nbsp;</p>
<pre name="code" class="java">public class Visitor {
	
	public void process(Service service){
		// 默认业务
	}
	
	public void process(Saving service){
		// 存款
	}
	
	public void process(Draw service){
		// 提款
	}
	
	public void process(Fund service){
		// 基金
	}
} </pre>
&nbsp;
<p>接着我们定义业务基类。</p>
<p>&nbsp;</p>
<pre name="code" class="java">public class Service {
	public void accept(Visitor visitor) {
		visitor.process(this);	
	}
} </pre>
<p>&nbsp;</p>
<p>不同的业务类。</p>
<pre name="code" class="java">public class Saving extends Service {
	//各种业务处理流程
}</pre>
&nbsp;
<pre name="code" class="java">public class Draw extends Service {
	//各种业务处理流程
}</pre>
&nbsp;
<pre name="code" class="java">public class fund extends Service {
	//各种业务处理流程
}</pre>
&nbsp;
<p>好了，接下来就是我们的访问者与到来的客户之间的交互了。</p>
<pre name="code" class="java">public class Client {
	public static void main(String[] args) {
		Service s1 = new Saving();
		Service s2 = new Draw();
		Service s3 = new Fund();
		
		Visitor visitor = new Visitor();
		
		s1.accept(visitor);
		s2.accept(visitor);
		s3.accept(visitor);
	}
}</pre>
&nbsp;
<p>后话：专门设定一个访问者的职位还是有点多余，于是后来银行经理请设备公司做了一个排号机来代替访问者。</p>
<p>&nbsp;</p>
<p><strong><span style="font-size: medium;">总结</span>
</strong>
</p>
<p>Visitor模式实际上是利用的语言本身的特性，见Vistor类的各个函数，通过不同的参数来自动查找相应的处理函数。</p>
<p>&nbsp;</p>
<p>采用Visitor的好处如上面说到的那样，当需要改变其中一项业务的处理时，不需要每个地方都进行修改，而只需要改动Visitor类中相应的处理函数就可以了。也就是说它适合于业务处理时常发生变动的情况。</p>
<p>&nbsp;</p>
<p>当然，Visitor也有它自身的限制。它不适合于业务数量的经常变化，因为一旦新增或删除一些Service时，需要对visitor进行相应的增删。也就是说具体Service与Visitor是耦合的。</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://smartfool.javaeye.com/blog/207092#comments" style="color:red;">已有 <strong>19</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 23 Jun 2008 14:04:32 +0800</pubDate>
        <link>http://smartfool.javaeye.com/blog/207092</link>
        <guid>http://smartfool.javaeye.com/blog/207092</guid>
      </item>
      <item>
        <title>[翻译]Reflection in Action</title>
        <author>lintomny</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://smartfool.javaeye.com">lintomny</a>&nbsp;
          链接：<a href="http://smartfool.javaeye.com/blog/164927" style="color:red;">http://smartfool.javaeye.com/blog/164927</a>&nbsp;
          发表时间: 2008年02月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          原文：http://today.java.net/pub/a/today/2008/02/12/reflection-in-action.html<br /><br />你曾经为IDE会自动的列举出所有你所编写的类的详情，甚至连私有的字段和方法也&ldquo;难逃魔掌&rdquo;而感到惊讶吗？此外，这些IDE居然还能够识别那些并不提供源码并压缩成JAR文件的类。它们是怎么做到的？<br /><br />这些都是因为反射。<br /><br />本文将通过逐步列举一个类的内容，来阐明反射是如何被用来&ldquo;撬动&rdquo;编程的。同时逐步形成高级别的抽象。我们将会从一个十分简单的例子开始，并一步步地在一个程序中实施反射。<br /><h2>什么是反射？</h2>反射是一种机制，它允许动态发现和绑定类、方法、字段，以及所有其他的由语言所产生的元素。反射可以做的不仅仅是简单地列举类、字段以及方法。通过反射，我们可以还能够在需要时完成创建实例、调用方法以及访问字段的工作。<br /><br />大多数程序员曾使用过动态类载入技术来载入他们的JDBC驱动。这种载入方法类似于下面这一段载入JDBC驱动实例的代码片段：<br /><br /><pre name="code" class="java">Class.forName(&quot;com.mysql.jdbc.Driver&quot;).newInstance();</pre><h2>为何与何时使用反射？</h2>反射提供了一个高级别的抽象，换句话说，反射允许我们在程序运行时对手头上的对象进行检查并运行。举个例子，想像一下，当你在执行那相同的任务时&mdash;&mdash;如像上面的例子那样在若干的对象中查找一个实例，你可以选择为每一个不同的对象写相同的代码，也可以使用反射来完成这项任务。或许你已经开始意识到了，反射可以减少近似的代码的维护量。因为使用了反射，你的实例查找代码将会对其他类起作用。我们稍后将会演示这个例子。我已经将它加入到这篇文章里，以便向你展示我们如何从反射中得利。<br />动态发现<br />下面我们以发现一个类的内容并列出它的构造子，字段，方法作为开始吧。这并不实用，但它能让我们直观地抓住反射的原理及其了解其API。<br /><br />创建一个Product类，如下所示。所有我们的例子都将放到了相同的package里，叫ria。<br /><br /><pre name="code" class="java">package ria;

public class Product {
private String description;

private long id;

private String name;

private double price;

//省略若干Getter与Setter
}</pre>&nbsp;<br /><br />创建好Product类后，我们下面继续创建第二个类，叫ReflectionUtil。它将列举出第一个类(Product)的详情。或许你已经预料到了，这个类会包含一些实用的方法，它们将完成这个程序所需要的反射功能。目前，这个类只会包含一个方法，describeInstance(Object)，它需要一个类型为Object的参数。<br /><br />类ReflectionUtil的代码如下所示。<br /><br /><pre name="code" class="java">package ria;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectionUtil {

public static void describeInstance(Object object) {
Class&lt;?&gt; clazz = object.getClass();

Constructor&lt;?&gt;[] constructors = clazz.getDeclaredConstructors();
Field[] fields = clazz.getDeclaredFields();
Method[] methods = clazz.getDeclaredMethods();

System.out.println(&quot;Description for class: &quot; + clazz.getName());
System.out.println();
System.out.println(&quot;Summary&quot;);
System.out.println(&quot;-----------------------------------------&quot;);
System.out.println(&quot;Constructors: &quot; + (constructors.length));
System.out.println(&quot;Fields: &quot; + (fields.length));
System.out.println(&quot;Methods: &quot; + (methods.length));

System.out.println();
System.out.println();
System.out.println(&quot;Details&quot;);
System.out.println(&quot;-----------------------------------------&quot;);

if (constructors.length &gt; 0) {
System.out.println();
System.out.println(&quot;Constructors:&quot;);
for (Constructor&lt;?&gt; constructor : constructors) {
System.out.println(constructor);
}
}

if (fields.length &gt; 0) {
System.out.println();
System.out.println(&quot;Fields:&quot;);
for (Field field : fields) {
System.out.println(field);
}
}

if (methods.length &gt; 0) {
System.out.println();
System.out.println(&quot;Methods:&quot;);
for (Method method : methods) {
System.out.println(method);
}
}
}
}</pre>&nbsp;<br />Java包含了一组反射相关的类，它们打包进了反射API(Reflection API)中。构造子类(Constructor)、字段类(Field)以及方法类(Method)便是其中的一部分。如同众所周知的Class类一样，它们在Java中被用来在程序中描述对象。为了描述一个对象，我们需要知道这个对象是由什么组成的。我们如何开始呢？那就从类开始吧，它包含了我们所有的代码。<br /><br /><pre name="code" class="java">Class&lt;?&gt; clazz = object.getClass();</pre><br />注意这里的泛型声明Class&lt;?&gt;。泛型，简单地说，就是通过限定给出的实例是某种类型的，从而提供类型安全(type-safe)的操作。我们的方法(describeInstance(Object))并不绑定到一个特定类型上，它被设计为对任意给出的对象都能正常运行。因此，那无限制的通配符，&lt;?&gt;，将会被使用到。<br /><br />Class类有一些方法，下面我们将集中于那些对我们有用的方法上。下面的代码片段中列出了这些方法。<br /><br /><pre name="code" class="java">Constructor&lt;?&gt;[] constructors = clazz.getDeclaredConstructors();
Field[] fields = clazz.getDeclaredFields();
Method[] methods = clazz.getDeclaredMethods();</pre><br />上面的这些来自Class类的方法返回了一组构造子、字段、方法，这是它们组成了这个对象。<br /><br />注意那个Class类含有两组getter方法：一组在它们的名字中包含了declared单词，而另一组没有。不同之处在于，getDeclaredMethods()会返回所有属于这个类的方法，而getMethods()则只返回声明为public的方法。这对于理解为何只有在这个类中声明的方法才予以返回的原因同样重要。继承的方法是不会被检索到的。<br /><br />了解ReflectionUtil类并没有对一个关于Product类的引用十分重要。我们需要另一个类来创建一个Product实例并打印出它的详情。<br /><br /><pre name="code" class="java">package ria;

public class Main {
public static void main(String[] args) throws Exception {
Product product = new Product();
product.setId(300);
product.setName(&quot;My Java Product Name&quot;);
product.setDescription(&quot;My Java Product description&quot;);
product.setPrice(10.10);

ReflectionUtil.describeInstance(product);
}
}</pre><br />上面的这个类运行后应该能输出下面的这段信息（或一些近似的信息）：<br /><br /><pre name="code" class="java">Description for class: ria.Product

Summary
-----------------------------------------
Constructors: 1
Fields: 4
Methods: 8


Details
-----------------------------------------

Constructors:
public ria.Product()

Fields:
private java.lang.String ria.Product.description
private long ria.Product.id
private java.lang.String ria.Product.name
private double ria.Product.price

Methods:
public java.lang.String ria.Product.getName()
public long ria.Product.getId()
public void ria.Product.setName(java.lang.String)
public void ria.Product.setId(long)
public void ria.Product.setDescription(java.lang.String)
public void ria.Product.setPrice(double)
public java.lang.String ria.Product.getDescription()
public double ria.Product.getPrice()</pre><br />为了让这个方法更加有用，我们可以加入打印出这个实例中定义的字段的值的功能。Field类有一个叫get(Object)的方法，它返回给定的实例的相应字段的值。<br /><br />现在就以我们的Procuct类来举个例子吧。这个类有四个实例变量。由于获取的值依赖于实例，因此不同的实例可能有不同的值。所以，必须向Field提供实例作为参数输入，这样我们才能够获取这个实例的对应的字段的值。如下所示：<br /><br />field.get(object)<br /><br />这里的field是Field的一个实例，同时object是为一个任意Java类的实例。<br /><br />在我们草率地开始增加代码前，我们必须认识到这么一个事实，那就是类的字段的私有访问性是可以修改的。如果我们调用一个标记为private的字段的 Field类的get(Object)方法，这样会抛出一个异常。因此，我们需要在着手访问那个字段的值前，调用这个Field类的方法 setAccessible(boolean)，并传递true作为参数进去。<br /><br />field.setAccessible(true);<br /><br />现在，我们知道了所有获取字段的值的相关小技巧了，我们可以在刚才那个decribeInstance(Object)方法下面接着增加如下的代码了。<br /><br />if (fields.length &gt; 0) {<br />  System.out.println();<br />  System.out.println();<br />  System.out.println(&quot;Fields' values&quot;);<br />  System.out.println(&quot;-----------------------------------------&quot;);<br />  for (Field field : fields) {<br />    System.out.print(field.getName());<br />    System.out.print(&quot; = &quot;);<br />    try {<br />      field.setAccessible(true);<br />      System.out.println(field.get(object));<br />    } catch (IllegalAccessException e) {<br />      System.out.println(&quot;(Exception Thrown: &quot; + e + &quot;)&quot;);<br />    }<br />  }<br />}<br /><br />为了给你显示这段代码的威力，我来创建一个java.awt.Rectangle类的实例吧，用这段增强版的describeInstance(Object)代码来打印出这个实例的详情。<br /><br />Rectangle rectangle = new Rectangle(1, 2, 100, 200);<br />ReflectionUtil.describeInstance(rectangle);<br /><br />上面的这个代码片段应该能输出一些类似下面的这些信息。提示一下，由于显示的信息过长，部分信息被省略掉了。<br /><br />Description for class: java.awt.Rectangle<br /><br />Summary<br />-----------------------------------------<br />Constructors: 7<br />Fields:       5<br />Methods:      39<br /><br /><br />Details<br />-----------------------------------------<br /><br />Constructors:<br />public java.awt.Rectangle()<br />public java.awt.Rectangle(java.awt.Rectangle)<br />public java.awt.Rectangle(int,int,int,int)<br />public java.awt.Rectangle(int,int)<br />public java.awt.Rectangle(java.awt.Point,java.awt.Dimension)<br />public java.awt.Rectangle(java.awt.Point)<br />public java.awt.Rectangle(java.awt.Dimension)<br /><br />Fields:<br />public int java.awt.Rectangle.x<br />public int java.awt.Rectangle.y<br />public int java.awt.Rectangle.width<br />public int java.awt.Rectangle.height<br />private static final long java.awt.Rectangle.serialVersionUID<br /><br />Methods:<br />public void java.awt.Rectangle.add(int,int)<br />public void java.awt.Rectangle.add(java.awt.Point)<br />public void java.awt.Rectangle.add(java.awt.Rectangle)<br />public boolean java.awt.Rectangle.equals(java.lang.Object)<br />public java.lang.String java.awt.Rectangle.toString()<br />public boolean java.awt.Rectangle.contains(int,int,int,int)<br />public boolean java.awt.Rectangle.contains(java.awt.Rectangle)<br />public boolean java.awt.Rectangle.contains(int,int)<br />public boolean java.awt.Rectangle.contains(java.awt.Point)<br />public boolean java.awt.Rectangle.isEmpty()<br />public java.awt.Point java.awt.Rectangle.getLocation()<br />public java.awt.Dimension java.awt.Rectangle.getSize()<br />public void java.awt.Rectangle.setSize(java.awt.Dimension)<br />public void java.awt.Rectangle.setSize(int,int)<br />public void java.awt.Rectangle.resize(int,int)<br />private static native void java.awt.Rectangle.initIDs()<br />public void java.awt.Rectangle.grow(int,int)<br />public boolean java.awt.Rectangle.intersects(java.awt.Rectangle)<br />private static int java.awt.Rectangle.clip(double,boolean)<br />public java.awt.geom.Rectangle2D java.awt.Rectangle.createIntersection(java.<br />public java.awt.geom.Rectangle2D java.awt.Rectangle.createUnion(java.awt.geo<br />public java.awt.Rectangle java.awt.Rectangle.getBounds()<br />public java.awt.geom.Rectangle2D java.awt.Rectangle.getBounds2D()<br />public double java.awt.Rectangle.getHeight()<br />public double java.awt.Rectangle.getWidth()<br />public double java.awt.Rectangle.getX()<br />public double java.awt.Rectangle.getY()<br />public boolean java.awt.Rectangle.inside(int,int)<br />public java.awt.Rectangle java.awt.Rectangle.intersection(java.awt.Rectangle)<br />public void java.awt.Rectangle.move(int,int)<br />public int java.awt.Rectangle.outcode(double,double)<br />public void java.awt.Rectangle.reshape(int,int,int,int)<br />public void java.awt.Rectangle.setBounds(int,int,int,int)<br />public void java.awt.Rectangle.setBounds(java.awt.Rectangle)<br />public void java.awt.Rectangle.setLocation(java.awt.Point)<br />public void java.awt.Rectangle.setLocation(int,int)<br />public void java.awt.Rectangle.setRect(double,double,double,double)<br />public void java.awt.Rectangle.translate(int,int)<br />public java.awt.Rectangle java.awt.Rectangle.union(java.awt.Rectangle)<br /><br /><br />Fields' values<br />-----------------------------------------<br />x = 1<br />y = 2<br />width = 100<br />height = 200<br />serialVersionUID = -4345857070255674764<br />创建一个新的使用反射的实例<br /><br />反射可以用来创建一个对象的实例。关于动态创建对象的实例有许多例子，如前面所说的动态载入一个JDBC驱动。更进一步，我们可以使用构造子(Constructor)类来创建新实例，特别是那些实例化时需要参数的实例。将下面的两个重载的方法加入到我们的ReflectionUtil中。<br /><br /> <br />public static &lt;T&gt; T newInstance(Class&lt;T&gt; clazz)<br />    throws IllegalArgumentException, SecurityException,<br />      InstantiationException, IllegalAccessException,<br />      InvocationTargetException, NoSuchMethodException {<br />  return newInstance(clazz, new Class[0], new Object[0]);<br />}<br /><br />public static &lt;T&gt; T newInstance(Class&lt;T&gt; clazz, Class&lt;?&gt;[] paramClazzes,<br />      Object[] params) throws IllegalArgumentException,<br />        SecurityException, InstantiationException, IllegalAccessException,<br />        InvocationTargetException, NoSuchMethodException {<br /><br />    return clazz.getConstructor(paramClazzes).newInstance(params);<br />}<br /><br />注意，方法newInstance(Object[])在构造子参数不匹配的时候可能会抛出一个异常。被实例化的类必须包含一个给定签名的构造子。<br /><br />第一个方法(newInstance(Class&lt;T&gt;))可以用来实例化任何一个拥有默认构造子的类的对象。否则可以使用第二个方法：传递参数的类型以及其值，当匹配上对应的构造子后就会执行相应的实例化。举个例子，类Rectangle就可以通过使用含有四个int类型的参数的构造子来进行实例化。使用的代码如下所示：<br /><br />Object[] params = { 1, 2, 100, 200 };<br />Class[] paramClazzes = { int.class, int.class, int.class, int.class };<br />Rectangle rectangle = ReflectionUtil.newInstance(<br />                               Rectangle.class, paramClazzes, params);<br />System.out.println(rectangle);<br /><br />上面的这段代码将产生如下的输出。<br /><br />java.awt.Rectangle[x=1,y=2,width=100,height=200]<br />通过反射改变字段的值<br />字段的值可以使用反射来进行设置，方法类似于如何使用反射来读取它们。需要注意的是在设置这些字段的值前要设置它们的可访问性，不然就会抛出异常的。<br /><br />field.setAccessible(true);<br />field.set(object, newValue);<br /><br />我们可以十分容易地编写出一个方法，用它来设置任何对象的值，就如同下面列出的例子一般。<br /><br />public static void setFieldValue(Object object, String fieldName,<br />      Object newValue) throws NoSuchFieldException,<br />      IllegalArgumentException, IllegalAccessException {<br />  Class&lt;?&gt; clazz = object.getClass();<br />  Field field = clazz.getDeclaredField(fieldName);<br />  field.setAccessible(true);<br />  field.set(object, newValue);<br />}<br /><br />这个方法有一个不足，它只能检索出这个类定义的字段；继承而来的字段并不包括在内。这个问题可以通过下面的这个方法来得到解决，它将向这个对象的基类查询相应的Field类。<br /><br />public static Field getDeclaredField(Object object, String name)<br />      throws NoSuchFieldException {<br />  Field field = null;<br />  Class&lt;?&gt; clazz = object.getClass();<br />  do {<br />    try {<br />      field = clazz.getDeclaredField(name);<br />    } catch (Exception e) { }<br />  } while (field == null &amp; (clazz = clazz.getSuperclass()) != null);<br /><br />  if (field == null) {<br />    throw new NoSuchFieldException();<br />  }<br /><br />  return field;<br />}<br /><br />这个方法将返回给定名字的Field对象，如果找到的话；否则，就会抛出一个异常以提示这个类以及它的基类都没有这个字段。这个方法从给定的类开始查找，逐步向上地查找各个基类直到每一个Field都被遍历过。当然，也有可能没有基类。<br /><br />提示，所有的Java类都是继承于Object类。正如你所认识到的，Object类并不继承自己。所以Object类没有基类。<br /><br />将前文提到的方法setFieldValue(Object, String, Object)进行修改一下，以满足这种情况。修改如下黑体所示。<br /><br />public static void setFieldValue(Object object, String fieldName,<br />    Object newValue) throws IllegalArgumentException,<br />    IllegalAccessException, NoSuchFieldException {<br /><br />  Field field = getDeclaredField(object, fieldName);<br />  field.setAccessible(true);<br />  field.set(object, newValue);<br />}<br /><br />下面来创建另一个叫做Book的类，它泛化于前面所讨论过的Product类。我们将在此应用我们刚才所学习到的关于反射的知识。<br /><br />package ria;<br /><br />public class Book extends Product {<br />  private String isbn;<br /><br />  //Getters and setters are omitted for shortness<br />}<br /><br />现在我们用方法setFieldValue(Object, String, Object)来设置book的id值。<br /><br />Book book = new Book();<br />ReflectionUtil.setFieldValue(book, &quot;id&quot;, 1234L);<br />System.out.println(book.getId());<br /><br />上面这段代码将输出1234。<br /><br /><br /><br />累死了！<br />未完待续。。。。<br /><br /> <br /><p>&nbsp;</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://smartfool.javaeye.com/blog/164927#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 25 Feb 2008 23:24:50 +0800</pubDate>
        <link>http://smartfool.javaeye.com/blog/164927</link>
        <guid>http://smartfool.javaeye.com/blog/164927</guid>
      </item>
      <item>
        <title>jQuery库与其他JS库冲突的解决办法</title>
        <author>lintomny</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://smartfool.javaeye.com">lintomny</a>&nbsp;
          链接：<a href="http://smartfool.javaeye.com/blog/152222" style="color:red;">http://smartfool.javaeye.com/blog/152222</a>&nbsp;
          发表时间: 2008年01月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          现在的js库很多，而且各有所长。像我，就比较喜欢jQuery，但同时也会使用一下其他的js库，如YUI，DWR什么的。但是它们却时不时地相互闹些小矛盾，真是让人头痛。究其原因，原来是它们的全局对象定义冲突了，特别是变量&rdquo;$&rdquo;，几乎百分之百要在这中招。怎么办？呵呵，看我的！<br /><br />重载$函数。使用jQuery.noConflict()就可以通过重载$函数，从而区分开跟其他js库的重叠部分。例子如下：<br /><br /><pre name="code" class="js">&lt;script src=&quot;prototype.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;jquery.js&quot;&gt;&lt;/script&gt;
&lt;script&gt;
    jQuery.noConflict();

    // Use jQuery via jQuery(&hellip;)
    jQuery(document).ready(function(){
    jQuery(&rdquo;div&rdquo;).hide();
    });

    // Use Prototype with $(&hellip;), etc.
    $(&rsquo;someid&rsquo;).style.display = &lsquo;none&rsquo;;
&lt;/script&gt;</pre><br />记得要在载入完各js库后才能用jQuery.noConflict()进行重载哦，如例子中的prototype和jquery。<br /><br />当然我们也可以不使用其默认的名字空间，比如我喜欢使用 $j() 而不是 jQuery() 。<br /><br /><pre name="code" class="js">var $j = jQuery.noConflict();
$j(document).ready(function(){
    $j(&rdquo;div&rdquo;).hide();
});</pre>&nbsp;<br />呵呵，很简单吧。原文在<a href="http://docs.jquery.com/Using_jQuery_with_Other_Libraries" target="_blank">这里</a>。<p>&nbsp;</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://smartfool.javaeye.com/blog/152222#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 02 Jan 2008 00:29:28 +0800</pubDate>
        <link>http://smartfool.javaeye.com/blog/152222</link>
        <guid>http://smartfool.javaeye.com/blog/152222</guid>
      </item>
      <item>
        <title>Perl之旅(一)</title>
        <author>lintomny</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://smartfool.javaeye.com">lintomny</a>&nbsp;
          链接：<a href="http://smartfool.javaeye.com/blog/138245" style="color:red;">http://smartfool.javaeye.com/blog/138245</a>&nbsp;
          发表时间: 2007年11月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>学习一个知识，最好的温习方法是把它教给其他人。本着这个想法，我就来尝试着说说Perl。</p>
<h3>Perl是什么？</h3>
<p>它是一种脚本语言，自由且功能强大。你可以认为他是&ldquo;实用报表提取语言&rdquo;（Practical Extraction and Report Language），也可以称其为&ldquo;病态折中垃圾列表器&rdquo;(Pathologically Eclectic Rubbish Lister)。这两种解释在作者Larry Wall看来都是正确的。生活本是娱乐，又何必强加严肃呢。</p>
<p>或 者你已经在计算机书店见过关于Perl的书了。或者你还隐约记得封面上那只动物，嗯，是的，是头骆驼。 在计算机语言中，Perl被称为&ldquo;骆驼语言&rdquo;。作者Larry Wall就说过：&ldquo;Perl可能不好看或者不好闻，但是它能完成任务&rdquo;。而这不正是骆驼的特性吗&mdash;&mdash;不好看也不好闻，有时还向你吐唾，可是它总能完成那些 艰巨的任务。</p>
<p>开始的时候，这个艰巨的任务是从像新闻组邮件那样的文件中产生一些有用的报表给一个bug 报告系统。简单来说就是文本处理。Perl一开始就被设计为90%处理文本，10%针对其它情况。它的正则表达式功能之强大是其他编程语言无法达到的，并 且简单快捷。另外，设计Perl 时Larry 做了学多权衡：是让程序员更容易使用呢，还是对于初学者更容易学习呢。Larry 更倾向于前一种，因为学习只是一次，而使用是重复的。由此，当你没接触过Perl时看Perl的代码，你可能不知所云，可是当你接触过几周后并实际写程序 时会发现，写Perl脚本简直是一种幸福。当然，前提是你要去学习它。</p>
<p>好了，说那么多，还是来看个例子吧。这是一个循环数据1至10的程序。</p>
<blockquote>
<p><code>@group = 1..10;<br />
for (@group) {<br />
print &quot;$_\n&quot;;<br />
}<br />
</code></p>
</blockquote>
<p>看不懂？嗯，没关系，我们的Perl之旅才刚刚开始嘛。</p>
<h3>安装Perl环境</h3>
<p>如果你是在linux或这Unix下，基本上安装系统就已经自带了Perl了。如果没有，你也可以到<a href="http://downloads.activestate.com/ActivePerl/">这里</a>下载。rpm和deb格式的安装包都很简单，这里说说<a href="http://net.pku.edu.cn/~yhf/perl/perl_1.html#2、Perl在哪里?">下载源码自己编译的方法</a>吧。</p>
<p>安装过程为：</p>
<ol>
    <li>解压：</li>
    <p>        <code>     $gunzip ActivePerl-5.8.6.811-i686-linux.tar.gz<br />
    $tar -xvf  ActivePerl-5.8.6.811-i686-linux.tar.gz</code></p>
    <li>编译：</li>
    <p>        <code>     $make makefile</code></p>
    <li>放置：</li>
    将编译生成的可执行文件拷贝到可执行文件通常所在目录，如：<br />
    <code># copy &lt; compiled excutable file &gt; <compiled excutable="" file=""> /usr/local/bin/perl<compiled excutable="" file=""></compiled></compiled></code></ol>
    <p>注：这需要系统管理员权限。 </p>
    <p>至于windows下的安装就更简单了，一路Next就行了。</p>
    <p>最后，我们先来个最经典的Hello World作为我们的第一个Perl程序吧。</p>
    <blockquote>
    <p><code>#!/usr/local/bin/perl<br />
    print &quot;Hello world, Perl!&quot;;</code></p>
    </blockquote>
    <p>第一行为perl所在的目录，第二行为输出&ldquo;Hello world, Perl!&rdquo;。</p>
    未完待续&hellip;&hellip;
          <br/><br/>
          <span style="color:red;">
            <a href="http://smartfool.javaeye.com/blog/138245#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 05 Nov 2007 23:09:05 +0800</pubDate>
        <link>http://smartfool.javaeye.com/blog/138245</link>
        <guid>http://smartfool.javaeye.com/blog/138245</guid>
      </item>
      <item>
        <title>一个简单的JDBC例子</title>
        <author>lintomny</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://smartfool.javaeye.com">lintomny</a>&nbsp;
          链接：<a href="http://smartfool.javaeye.com/blog/135891" style="color:red;">http://smartfool.javaeye.com/blog/135891</a>&nbsp;
          发表时间: 2007年10月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          朋友开始学JAVA，刚学到JDBC，找我写个例子给他看看。心想这容易，可是打开eclispe却下不了手&mdash;&mdash;居然只记得有个DataSource、有个ResultSet，然后&hellip;&hellip;然后就没有了。查了Java doc才又想起。唉，看来这些零零散散的东西还是需要记下来才行。<br />
<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="comment">//&nbsp;载入驱动</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>Class.forName(<span class="string">&quot;com.mysql.jdbc.Driver&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span><span class="comment">//&nbsp;建立连接</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>Connection&nbsp;con&nbsp;=&nbsp;DriverManager.getConnection(&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;<span class="string">&quot;jdbc:mysql://localhost:3306/demo&quot;</span><span>,&nbsp;</span><span class="string">&quot;test&quot;</span><span>,&nbsp;</span><span class="string">&quot;test&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class=""><span><span class="comment">//&nbsp;创建状态</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>Statement&nbsp;stmt&nbsp;=&nbsp;con.createStatement();&nbsp;&nbsp;</span></li>
    <li class=""><span><span class="comment">//&nbsp;执行SQL语句，返回结果集</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>ResultSet&nbsp;rs&nbsp;=&nbsp;stmt.executeQuery(<span class="string">&quot;SELECT&nbsp;*&nbsp;FROM&nbsp;person&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class=""><span><span class="comment">//&nbsp;对结果集进行处理</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span><span class="keyword">while</span><span>&nbsp;(rs.next())&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;<span class="keyword">int</span><span>&nbsp;id&nbsp;=&nbsp;rs.getInt(</span><span class="string">&quot;id&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;String&nbsp;name&nbsp;=&nbsp;rs.getString(<span class="string">&quot;name&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;Integer&nbsp;age&nbsp;=&nbsp;rs.getObject(<span class="string">&quot;age&quot;</span><span>)&nbsp;==&nbsp;</span><span class="keyword">null</span><span>&nbsp;?&nbsp;</span><span class="keyword">null</span><span>&nbsp;:&nbsp;rs.getInt(</span><span class="string">&quot;age&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;System.out.println(id&nbsp;+&nbsp;<span class="string">&quot;:&nbsp;&quot;</span><span>&nbsp;+&nbsp;name&nbsp;+&nbsp;</span><span class="string">&quot;&nbsp;&quot;</span><span>&nbsp;+&nbsp;age);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>}&nbsp;&nbsp;</span></li>
    <li class="alt"><span><span class="comment">//&nbsp;释放资源</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>stmt.close();&nbsp;&nbsp;</span></li>
    <li class="alt"><span>con.close();&nbsp;&nbsp;</span></li>
</ol>
</div>
<br />
顺便提一下，在JDBC中对于如int，long，boolean等值的返回是不会返回null的。如getInt()，如果数据库中值为NULL，则返回的时候是0。这样我们就<strong>不知道到底数据库中存的是NULL还是0</strong>。怎么办呢？幸好JDBC还提供给我们这么一个函数&mdash;&mdash;getObject()。是的，它返回的是一个Object对象，这样我们就可以对这个Object对象进行判空，从而获悉数据库中此值是NULL还是0了。<br />
<br />
我们获取这些有可能为NULL的值的时候，可以这么写：<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<ol class="dp-j" start="1">
    <li class=""><span>&nbsp;Integer&nbsp;age&nbsp;=&nbsp;rs.getObject(<span class="string">&quot;age&quot;</span><span>)&nbsp;==&nbsp;</span><span class="keyword">null</span><span>&nbsp;?&nbsp;</span><span class="keyword">null</span><span>&nbsp;:&nbsp;rs.getInt(</span><span class="string">&quot;age&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<br />
（完）
          <br/><br/>
          <span style="color:red;">
            <a href="http://smartfool.javaeye.com/blog/135891#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 27 Oct 2007 16:23:58 +0800</pubDate>
        <link>http://smartfool.javaeye.com/blog/135891</link>
        <guid>http://smartfool.javaeye.com/blog/135891</guid>
      </item>
      <item>
        <title>Linux下写C程序</title>
        <author>lintomny</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://smartfool.javaeye.com">lintomny</a>&nbsp;
          链接：<a href="http://smartfool.javaeye.com/blog/129009" style="color:red;">http://smartfool.javaeye.com/blog/129009</a>&nbsp;
          发表时间: 2007年10月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div class="storycontent">
<p>在windows下写C程序是一件很容易的事，装好Turbo C就可以了，相信各位学过编程的都十分了解Turbo C吧。特别是现在大学里人人忙考级的情况下，二级C语言大概成了每个人默认考过的等级考试吧。可是在linux下又如何写C程序呢？其实，linux下写 C也是很容易的。IDE的话用 <ahref>eclipse 集成 <a href="http://www.eclipse.org/cdt/">CDT</a> 模块就行了。当然这属于重量级的了，就如同VC++之于windows一样。那有没有像Turbo C那样的小工具呢，主要也就是用到它的编译功能。恩，这就是这次我们要说的 <a href="http://gcc.gnu.org/">GCC</a> 了。</ahref></p>
<p>根据 <a href="http://zh.wikipedia.org/wiki/GCC">wikipedia</a> (<a href="http://www.google.com/search?hl=zh-CN&amp;newwindow=1&amp;rlz=1B3GGGL_zh-CNCN241CN241&amp;defl=zh-CN&amp;q=define:GCC&amp;sa=X&amp;oi=glossary_definition&amp;ct=title">google</a>)上的定义，GCC（GNU Compiler Collection，GNU编译器套装），是一套由GNU开发的编程语言编译器。它是GNU toolchain的关键部分，亦是开放源代码的类Unix操作系统的标准编译器。</p>
<p>GCC 跟Turbo C的处理过程大同小异，其由C语言源代码文件生成可执行文件的过程不仅仅是编译的过程，而是要经历四个相互关联的步骤∶预处理(也称预编译， Preprocessing)、编译(Compilation)、汇编(Assembly)和连接(Linking)。所以，基本上可以这么说，用过 Turbo C的，很容易就会习惯GCC了。</p>
<p>好了，现在我们来写个简单的程序吧。首先是安装GCC，如果你使用的是Ubuntu，则在终端中输入以下命令来安装GCC。</p>
<blockquote>
<p><strong>sudo apt-get install gcc</strong></p>
</blockquote>
<p>安 装好GCC就可以写程序了？别急，现在GCC什么文件都还不能编译呢。还记得在Turbo C上我们不是还要设置头文件的路径吗？是的，我们需要安装这些头文件，这就是build- essential软件包。安装好这个包，系统就会自动安装上g++,libc6-dev,linux-libc-dev,libstdc++6-4.1 - dev等一些必须的软件和头文件的库。我们可以在终端中输入下面命令来安装：</p>
<blockquote>
<p><strong>sudo apt-get install build-essential</strong></p>
</blockquote>
<p>好了，环境搭建完毕，就让我们开始动手写程序吧。首先来个最经典的hello world热热身。用 <a href="http://www.gnome.org/projects/gedit/">gedit</a> 或者 <a href="http://www.linuxsir.org/main/?q=node/206">vi</a> 写下这个程序，并保存为hello.c。</p>
<blockquote>
<p><code><strong>#include &lt;stdio.h&gt;<br />
int main()<br />
{<br />
printf( &quot;Hello world!\n&quot; );<br />
return 0;<br />
}</strong> </code></p>
</blockquote>
<p>将文件保存为hello.c后，在终端中使用敲入以下命令来使用GCC对程序进行编译。</p>
<blockquote>
<p><strong>gcc hello.c -o hello</strong></p>
</blockquote>
<p>编译通过后，我们会在当前目录中看到hello文件，这就是编译后生成的可执行文件。好了，我们来运行一下它，来跟world打个招呼。</p>
<blockquote>
<p><strong>./hello</strong></p>
</blockquote>
<p>我们可以看到在终端中输出了&rdquo;Hello world!&rdquo;，这就说明我们的程序运行成功了。</p>
<p>最后，需要特别说明的是GCC中对于文件后缀的规定有点特殊，特别是C++源代码文件的后缀不是cpp，而是cc或cxx。</p>
<ul>
    <li>.c为后缀的文件，C语言源代码文件；</li>
    <li>.a为后缀的文件，是由目标文件构成的档案库文件；</li>
    <li>.C，.cc或.cxx 为后缀的文件，是C++源代码文件；</li>
    <li>.h为后缀的文件，是程序所包含的头文件；</li>
    <li>.i 为后缀的文件，是已经预处理过的C源代码文件；</li>
    <li>.ii为后缀的文件，是已经预处理过的C++源代码文件；</li>
    <li>.m为后缀的文件，是Objective-C源代码文件；</li>
    <li>.o为后缀的文件，是编译后的目标文件；</li>
    <li>.s为后缀的文件，是汇编语言源代码文件；</li>
    <li>.S为后缀的文件，是经过预编译的汇编语言源代码文件。 </li>
</ul>
<p>好了，发挥想象力尽情写程序吧！</p>
</div>
          <br/><br/>
          <span style="color:red;">
            <a href="http://smartfool.javaeye.com/blog/129009#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 03 Oct 2007 18:58:13 +0800</pubDate>
        <link>http://smartfool.javaeye.com/blog/129009</link>
        <guid>http://smartfool.javaeye.com/blog/129009</guid>
      </item>
      <item>
        <title>Bridge - 桥接模式</title>
        <author>lintomny</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://smartfool.javaeye.com">lintomny</a>&nbsp;
          链接：<a href="http://smartfool.javaeye.com/blog/74659" style="color:red;">http://smartfool.javaeye.com/blog/74659</a>&nbsp;
          发表时间: 2007年04月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <br />
<font size="4"><strong>意图</strong></font><br />
<em><strong>将抽象部分与它的实现部分分离，使它们都可以独立地变化。(GoF)</strong></em><br />
<br />
<font size="4"><strong>场景</strong></font><br />
现在我们有很多表要处理，同时又有很多操作要做。最简单的做法是在一个类里做完所有的操作，如我们在EJB服务器端的实现中进行JDBC操作。可是这样一来这个类将无比巨大，大到四只眼(眼睛兄)都看不过来！<br />
<br />
有什么好办法能够降低这样操作的杂乱性呢？我们注意到这里有两个概念，分别是&ldquo;<strong>表单(Table)</strong>&rdquo;和&ldquo;<strong>操作(Operator)</strong>&rdquo;。也就是说这里有两个部分&mdash;&mdash;<strong>&ldquo;抽象&rdquo;和&ldquo;实现&rdquo;</strong>。我们将这两个部分进行分离，然后根据需要，分别继承和实现表单和操作。这样我们就可以方便地通过<strong>表单和操作的组合</strong>来实现我们的工作了。<br />
<br />
操作如：<br />
<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span>Table&nbsp;tbl1&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;Table1(</span><span class="keyword">new</span><span>&nbsp;Insert());&nbsp;&nbsp;</span></span></li>
    <li class=""><span>tbl1.work();&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>Table&nbsp;tbl2&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;Table2(</span><span class="keyword">new</span><span>&nbsp;Update());&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>tbl2.work();&nbsp;&nbsp;</span></li>
</ol>
</div>
<br />
Table1和Table2都是Table的子类，他们都映射到数据库中特定的表。Insert和Update都是接口Operator的实现，分别完成特定的数据库操作。<br />
<br />
好了，下面来先看看Operator的实现代码。<br />
<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">interface</span><span>&nbsp;Operator&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">/**</span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;操作</span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;arg&nbsp;传入的参数</span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;操作结果</span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;work(String&nbsp;arg);&nbsp;&nbsp;</span></li>
    <li class="alt"><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<br />
我们需要能对数据库进行插入和修改操作，因此分别建立Insert和Update类。<br />
<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="comment">//&nbsp;插入操作</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Insert&nbsp;</span><span class="keyword">implements</span><span>&nbsp;Operator&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;String&nbsp;work(String&nbsp;arg)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;rs&nbsp;=&nbsp;<span class="string">&quot;insert&nbsp;&quot;</span><span>&nbsp;+&nbsp;arg;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;rs;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="comment">//&nbsp;修改操作</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Update&nbsp;</span><span class="keyword">implements</span><span>&nbsp;Operator&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;String&nbsp;work(String&nbsp;arg)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;rs&nbsp;=&nbsp;<span class="string">&quot;update&nbsp;&quot;</span><span>&nbsp;+&nbsp;arg;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;rs;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<br />
好了，我们再来看看抽象部分的实现。这里我们的对象是Table。<br />
<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">abstract</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Table&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;内置一个操作接口</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">protected</span><span>&nbsp;Operator&nbsp;impl&nbsp;=&nbsp;</span><span class="keyword">null</span><span>;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;Table(Operator&nbsp;impl)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.impl&nbsp;=&nbsp;impl;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">/**</span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;由子类来具体实现此操作</span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">abstract</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;work();&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<br />
现在我们有两个表单需要进行操作，他们分别是Table1和Table2。<br />
<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Table1&nbsp;</span><span class="keyword">extends</span><span>&nbsp;Table&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;Table1(Operator&nbsp;impl)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">super</span><span>(impl);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;work()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<span class="keyword">this</span><span>.impl.work(</span><span class="string">&quot;Table1&quot;</span><span>));&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Table2&nbsp;</span><span class="keyword">extends</span><span>&nbsp;Table&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;Table2(Operator&nbsp;impl)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">super</span><span>(impl);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;work()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<span class="keyword">this</span><span>.impl.work(</span><span class="string">&quot;Table2&quot;</span><span>));&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<br />
这样我们在进行数据库的操作的时候，便可以随意地根据实际情况进行<strong>表单与操作的组合</strong>，<strong>将表单与操作桥接在一起</strong>来完成我们的任务。<br />
<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="comment">//&nbsp;对table1进行插入操作</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>Table&nbsp;tbl1&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;Table1(</span><span class="keyword">new</span><span>&nbsp;Insert());&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>tbl1.work();&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span><span class="comment">//&nbsp;对table2进行修改操作</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>Table&nbsp;tbl2&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;Table2(</span><span class="keyword">new</span><span>&nbsp;Update());&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>tbl2.work();&nbsp;&nbsp;</span></li>
</ol>
</div>
<br />
<font size="4"><strong>小结</strong></font><br />
Bridge设计模式感觉上是通过将对象与操作进行分离，然后对这两个基本概念进行继承及实现，通过对对象及操作的各种组合来完成相应的工作。<br />
<br />
P.S.一直想不到一个好的例子来说明Bridge模式，今天吃早饭的时候突然想到可以用来应用于数据库操作。这几天就先按照这种想法做一个demo看看效果如何。呵呵，不知道会不会又是一种重复造轮子的行为呢？不过作为一种实践体会我觉得也很值得。<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
          <br/><br/>
          <span style="color:red;">
            <a href="http://smartfool.javaeye.com/blog/74659#comments" style="color:red;">已有 <strong>13</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 27 Apr 2007 17:31:00 +0800</pubDate>
        <link>http://smartfool.javaeye.com/blog/74659</link>
        <guid>http://smartfool.javaeye.com/blog/74659</guid>
      </item>
      <item>
        <title>Adapter - 适配器模式</title>
        <author>lintomny</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://smartfool.javaeye.com">lintomny</a>&nbsp;
          链接：<a href="http://smartfool.javaeye.com/blog/74417" style="color:red;">http://smartfool.javaeye.com/blog/74417</a>&nbsp;
          发表时间: 2007年04月24日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <font size="4"><strong>意图</strong></font><br />
<em><strong>将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。(GoF)</strong></em><br />
<br />
<font size="3"><strong>场景</strong></font><br />
相信很多人都知道什么是显卡，也有很多人知道显卡的本名&mdash;&mdash;图形适配器。恩，是的，正好这回说说Apater模式，就拿显卡来例子来分析一下Adapter模式。<br />
<br />
我们知道显示器(Client)是用来显示图形的，它是不能显示数据，它只能够接受来自图形发送设备Target的信号。可是我们手头上只有CPU(Adaptee)这个产生各种描述图形的数据的数据发送器。我们需要将这些数据让显示器进行显示，可是这两个部件却是不兼容的。于是我们需要一个中间设备，它能够将CPU&ldquo;适配&rdquo;于显示器，这便是我们的显卡&mdash;&mdash;图形适配器(Adapter)。<br />
<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="comment">//&nbsp;图形发送设备</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Target&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">/**</span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;传送图形信号</span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;String&nbsp;request()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;</span><span class="string">&quot;Graphic&nbsp;sender&quot;</span><span>;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>}&nbsp; <br />
    </span></li>
</ol>
</div>
<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="comment">//&nbsp;显示器</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Client&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Target&nbsp;target&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;Targete();&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(target.request());&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<br />
可是我们的CPU(Adaptee)只能输出0/1数据，他是个计算器，而不是图形发送设备(Target)。<br />
<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="comment">//&nbsp;CPU</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Adaptee&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">/**</span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;CPU输出的数据</span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;String&nbsp;getData()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;</span><span class="string">&quot;CPU&nbsp;data&quot;</span><span>;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<br />
这个时候我们的显卡(Adapter)的作用便体现出来了，它负责对CPU进行适配，通过将CPU传过来的数据转换成图形信号，从而将CPU伪装成一个图形发送设备。<br />
<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="comment">//&nbsp;显卡，即我们的适配器</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Adapter&nbsp;</span><span class="keyword">extends</span><span>&nbsp;Target&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp; <span class="comment">//&nbsp;被代理的设备</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;Adaptee&nbsp;apt&nbsp;=&nbsp;</span><span class="keyword">null</span><span>;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">/**</span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;装入被代理的设备</span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;Adapter(Adaptee&nbsp;apt)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.apt&nbsp;=&nbsp;apt;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">/**</span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;被代理的设备传过来的数据转换成为图形输出</span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;String&nbsp;request()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;apt.getData();&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<br />
这样，我们的电脑的显示流程就变成CPU－显卡－显示器：<br />
<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Client&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="comment">//&nbsp;CPU经过显卡的适配后&ldquo;变&rdquo;成了图形发送装置了</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Target&nbsp;target&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;Adapter(</span><span class="keyword">new</span><span>&nbsp;Adaptee());&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(target.request());&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li class="alt"><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<br />
上面的这种依赖于对象组合的Adapter模式叫做<strong>对象适配器(Object Adapter)</strong>。它的特征是继承/实现某一方的类(Target)，如这里的图形发送器，同时内部包含一个被适配的类(Adaptee)，如这里的CPU。通过重写其父类的方法来进行适配。<br />
<font size="3"><strong><br />
另一种的Adapter实现</strong></font><br />
对于Adapter模式，还有另外一种实现方式，这种适配方式叫做<strong>类适配器(Class Adapter)</strong>。它与Object Adapter的不同之处在于它继承被适配的对象。<br />
<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Adapter&nbsp;</span><span class="keyword">extends</span><span>&nbsp;Targer,&nbsp;Adaptee&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;......&nbsp;&nbsp;</span></li>
    <li class="alt"><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<br />
这样的代码在C++中是合法的，但是在Java中规定最多只能继承一个父类，而可以实现多个接口。所以我们需要建立一个IAdaptee的接口，然后将我们的Adapter继承Target同时实现IAdaptee。<br />
<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="comment">//&nbsp;IAdaptee接口</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">interface</span><span>&nbsp;IAdaptee {&nbsp;&nbsp;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span><span> </span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;String getData();&nbsp;&nbsp;</span></li>
    <li class="alt"><span>}&nbsp;&nbsp;&nbsp;</span></li>
</ol>
</div>
<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="comment">// Adaptee 实现IAdaptee</span><span>&nbsp; <br />
    </span></span></li>
    <li class=""><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span> Adaptee </span><span class="keyword">implements</span><span>&nbsp;IAdaptee {&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;......&nbsp;&nbsp;</span></li>
    <li class=""><span>}&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
</ol>
</div>
<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Adapter&nbsp;</span><span class="keyword">extends</span><span>&nbsp;Target&nbsp;</span><span class="keyword">implements</span><span>&nbsp;IAdaptee&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;IAdaptee&nbsp;apt&nbsp;=&nbsp;</span><span class="keyword">null</span><span>;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;Adapter(IAdaptee&nbsp;apt)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">this</span><span>.apt&nbsp;=&nbsp;apt;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;String&nbsp;request()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;apt.getData();&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;String&nbsp;getData()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;apt.getData();&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class=""><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<br />
对于我们的显示器(Client)方面，Class Adapter跟Object Adapter一样，所以不需要进行修改。<br />
<br />
对于Class Adapter，大家也看见了，在Adapter中因为是实现了IAdaptee接口，因此需要实现getData()的接口。一旦Target和IAdaptee拥有相同的方法时，会出现麻烦的。所以尽量优先使用Object Adapter的模式。<br />
<br />
<font size="4"><strong>小结</strong></font><br />
作为总结，我觉得<a href="http://ks.cn.yahoo.com/question/1307031100087.html">显卡本身的定义</a>便很能表达Apater设计模式：&ldquo;<strong>它是主机与显示器之间连接的&ldquo;桥梁&rdquo;，作用是控制电脑的图形输出，负责将CPU送来的的影象数据处理成显示器认识的格式，再送到显示器形成图象。</strong>&rdquo;
          <br/><br/>
          <span style="color:red;">
            <a href="http://smartfool.javaeye.com/blog/74417#comments" style="color:red;">已有 <strong>7</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 24 Apr 2007 19:16:03 +0800</pubDate>
        <link>http://smartfool.javaeye.com/blog/74417</link>
        <guid>http://smartfool.javaeye.com/blog/74417</guid>
      </item>
      <item>
        <title>Singleton - 单件创建模式</title>
        <author>lintomny</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://smartfool.javaeye.com">lintomny</a>&nbsp;
          链接：<a href="http://smartfool.javaeye.com/blog/73655" style="color:red;">http://smartfool.javaeye.com/blog/73655</a>&nbsp;
          发表时间: 2007年04月24日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <font size="3"><strong>意图</strong></font><br />
保证一个类仅有一个实例，并提供一个访问它的全局访问点。(G4)<br />
<br />
<font size="3"><strong>场景</strong></font><br />
不知大家用过Derby这个嵌入式数据库没有，同一时间只能有一个进程访问Derby。这样我们就需要设置一个全局唯一的操作类对进行Derby数据库的各种操作。Singleton便是解决这类问题的一颗银弹。<br />
<br />
在Java中static指定的属性在JVM中是全局唯一的，利用这一点我们便可以来实现Singlton的效果。<br />
* 注意要将默认的构造函数设置成private的，这样才能保证只能通过getSingleton()来获取单一的实例。<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Singleton&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">//&nbsp;单件，静态</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;Singleton&nbsp;me&nbsp;=&nbsp;</span><span class="keyword">null</span><span>; <br />
    </span></span></li>
    <li class="alt"><span><span><br />
    </span></span></li>
    <li class="alt"><span><span>&nbsp;&nbsp;&nbsp; </span></span><span><span class="comment">// 默认的构造函数设置成private，这样保证了只能通过getSingleton()来获得单一实例</span><span></span></span><span><span class="keyword"></span></span></li>
    <li class="alt"><span><span class="keyword">&nbsp;&nbsp;&nbsp; private</span><span>&nbsp;</span><span class="keyword"></span><span>Singleton() {}</span></span><span><span><br />
    </span></span></li>
    <li class=""><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">/**</span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;获取单件</span></span><span><span class="comment">，采用lazy方式创建单一实例</span></span><span> <br />
    </span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return</span>&nbsp;</span></li>
    <li class=""><span><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;Singleton&nbsp;getSingleton()&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>&nbsp;(me&nbsp;==&nbsp;</span><span class="keyword">null</span><span>)&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;me&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;Singleton();&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;me;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>}&nbsp; </span></li>
</ol>
</div>
          <br/><br/>
          <span style="color:red;">
            <a href="http://smartfool.javaeye.com/blog/73655#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 24 Apr 2007 00:37:18 +0800</pubDate>
        <link>http://smartfool.javaeye.com/blog/73655</link>
        <guid>http://smartfool.javaeye.com/blog/73655</guid>
      </item>
      <item>
        <title>Prototype - 原型创建模式</title>
        <author>lintomny</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://smartfool.javaeye.com">lintomny</a>&nbsp;
          链接：<a href="http://smartfool.javaeye.com/blog/72152" style="color:red;">http://smartfool.javaeye.com/blog/72152</a>&nbsp;
          发表时间: 2007年04月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>下面来说说Prototype模式。首先还是照旧先来看看牛人想出Prototype模式的意图。</p>
<p><strong>用原型实例制定创建对象的种类，并且通过拷贝这些原型创建新的对象。(G4)</strong></p>
<p><strong><font size="4">场景</font></strong></p>
<p>我们手头上已经得到一个Product实例了，现在我们由于业务的要求，需要再获取若干个完全一样或相近的Product，好完成其他的工作。这个时候我们要做的工作就是复制一个。按照以往的做法，我们是每要求复制出一个的时候，我们会先new出一个对象，然后逐个属性地先从样板Product中get出来再set到新对象中去。</p>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;ClassSample&nbsp;{ &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;String&nbsp;attrA&nbsp;=&nbsp;</span><span class="keyword">null</span><span>; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;String&nbsp;attrB&nbsp;=&nbsp;</span><span class="keyword">null</span><span>; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;...... &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span><span class="comment">//&nbsp;setter&nbsp;and&nbsp;getter </span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>}&nbsp;&nbsp;</span> </li>
</ol>
</div>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j">
    <li class="alt"><span><span><font color="#339966">// cs1为得到的样本</font></span></span> </li>
    <li class="alt"><span><span>ClassSample&nbsp;cs2&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;ClassSample(); &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>cs2.setAttrA(&nbsp;cs1.getAttrA()&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>cs2.setAttrB(&nbsp;cs1.getAttrB()&nbsp;); &nbsp;&nbsp;</span> </li>
    <li class=""><span>......&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>&nbsp;程序员总是为如何能够更懒惰而勤奋地努力着。这样的劳模可不是好的程序员该做的事，这种烦琐而重复性高的复制能不能只写一遍呢？答案是&ldquo;可以&rdquo;，而且很简单。我们只需要在原型对象中增加一个clone()函数即可，由类本身来帮我们完成这个复制工作。</p>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;ClassSample&nbsp;{&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;String&nbsp;attrA&nbsp;=&nbsp;</span><span class="keyword">null</span><span>;&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;String&nbsp;attrB&nbsp;=&nbsp;</span><span class="keyword">null</span><span>;&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;......&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;<span class="comment">//&nbsp;settter&nbsp;and&nbsp;getter</span><span>&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;<span class="comment">//&nbsp;clone</span><span>&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;ClassSample&nbsp;clone()&nbsp;{&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;ClassSample&nbsp;cs&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;ClassSample();&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;cs.setAttrA(<span class="keyword">this</span><span>.attrA);&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;cs.setAttrB(<span class="keyword">this</span><span>.attrB);&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;cs;&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;}&nbsp;&nbsp;</span> </li>
    <li class=""><span>}&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>&nbsp;这样，复制创建对象就简单了很多了。</p>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<ol class="dp-j">
    <li class="alt"><span><span>ClassSample&nbsp;cs2&nbsp;=&nbsp;cs1.clone();&nbsp;&nbsp;</span></span> </li>
</ol>
</div>
<br />
<p>&nbsp;本来故事到这里便结束了。可是由于Java为我们做了更多，让我们更方便地使用Prototype模式，为了让懒惰进行到底，也同时体谅一下Java的良苦用心，有义务要在这里说说Java为我们做的Prototype模式的简化。大家都知道在Java中所有的类都是java.lang.Object的子类，而且在Object中已经定义了clone()方法。通过使用这个clone()方法我们就可以简单方便地进行复制创建了。</p>
<p>可是这个clone()方法可不能随便使用，冒失失地调用surper.clone()是会抛出CloneNotSupportedException异常的。我们还需要实现Cloneable接口才行。</p>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;ClassSample&nbsp;</span><span class="keyword">implements</span><span>&nbsp;Cloneable&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;String&nbsp;attrA&nbsp;=&nbsp;</span><span class="keyword">null</span><span>;&nbsp;&nbsp;&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;String&nbsp;attrB&nbsp;=&nbsp;</span><span class="keyword">null</span><span>;&nbsp;&nbsp;&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;......&nbsp;&nbsp;&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;<span class="comment">//&nbsp;settter&nbsp;and&nbsp;getter&nbsp;&nbsp;</span><span>&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;<span class="comment">//&nbsp;clone&nbsp;&nbsp;</span><span>&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;ClassSample&nbsp;clone()&nbsp;</span><span class="keyword">throws</span><span>&nbsp;CloneNotSupportedException&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;ClassSample&nbsp;cs&nbsp;=&nbsp;(ClassSample) <span class="keyword">super</span><span>.clone();&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;cs;&nbsp;&nbsp;&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;</span> </li>
    <li class=""><span>}&nbsp;&nbsp;</span> </li>
</ol>
</div>
<p>简单的一句super.clone()就可以完成我们的各种setter,getter操作。确实很方便。&nbsp;</p>
<p>我们在进行clone的时候仍然使用下面的句子就可以进行对象复制创建了。</p>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<ol class="dp-j">
    <li class="alt"><span><span><span><span>ClassSample&nbsp;cs2&nbsp;=&nbsp;cs1.clone</span></span>();&nbsp;&nbsp;</span></span> </li>
</ol>
</div>
<p>&nbsp;(完)</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://smartfool.javaeye.com/blog/72152#comments" style="color:red;">已有 <strong>5</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 18 Apr 2007 13:02:00 +0800</pubDate>
        <link>http://smartfool.javaeye.com/blog/72152</link>
        <guid>http://smartfool.javaeye.com/blog/72152</guid>
      </item>
      <item>
        <title>Factory - 工厂模式</title>
        <author>lintomny</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://smartfool.javaeye.com">lintomny</a>&nbsp;
          链接：<a href="http://smartfool.javaeye.com/blog/71937" style="color:red;">http://smartfool.javaeye.com/blog/71937</a>&nbsp;
          发表时间: 2007年04月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          关于工厂模式，没什么好说的，实在太常见了。不过作为设计模式的完整性，还是将它写出来来。<br style="font-size: 18px;" />
<br style="font-size: 18px;" />
以前我们创建一个对象时通常是采用new的方式，如<br style="font-size: 18px;" />
<div class="code_title" style="font-size: 18px;">java 代码</div>
<div class="dp-highlighter" style="font-size: 18px;">
<ol class="dp-j" start="1" style="font-size: 18px;">
    <li class="alt" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;">Product proa&nbsp;=&nbsp;</span><span class="keyword" style="font-size: 18px; line-height: 27px;">new</span><span style="font-size: 18px; line-height: 27px;">&nbsp;ProductA();<br style="font-size: 18px; line-height: 27px;" />
    </span></span></li>
    <li class="alt" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;">Product prob&nbsp;=&nbsp;<span class="keyword" style="font-size: 18px; line-height: 27px;">new</span><span style="font-size: 18px; line-height: 27px;">&nbsp;ProductB();<br style="font-size: 18px; line-height: 27px;" />
    </span></span></li>
</ol>
</div>
<br style="font-size: 18px;" />
这样进行实例创建的一个结果是，当Product子类越来越多的时候，这样就需要修改new代码。这样是很麻烦的。一个解决的方法就是使用一个对象来管理这些对象的创建。这个用来创建对象的便是Factory。<br style="font-size: 18px;" />
<br style="font-size: 18px;" />
<em style="font-size: 18px;"><strong style="font-size: 18px;">定义一个用于创建对象的接口，让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。</strong></em>(G4)<br style="font-size: 18px;" />
<br style="font-size: 18px;" />
下面来看看具体的实现代码吧。
<div class="code_title" style="font-size: 18px;">java 代码</div>
<div class="dp-highlighter" style="font-size: 18px;">
<div class="bar" style="font-size: 18px;">&nbsp;</div>
<ol class="dp-j" start="1" style="font-size: 18px;">
    <li class="alt" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;"><span class="comment" style="font-size: 18px; line-height: 27px;">//&nbsp;工厂方法所创建的对象的接口</span><span style="font-size: 18px; line-height: 27px;">&nbsp;&nbsp;</span></span></li>
    <li class="" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;"><span class="keyword" style="font-size: 18px; line-height: 27px;">public</span><span style="font-size: 18px; line-height: 27px;">&nbsp;</span><span class="keyword" style="font-size: 18px; line-height: 27px;">interface</span><span style="font-size: 18px; line-height: 27px;">&nbsp;Product&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="alt" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;">&nbsp;&nbsp;......&nbsp;&nbsp;</span></li>
    <li class="" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;">}&nbsp;&nbsp;</span></li>
</ol>
</div>
<br style="font-size: 18px;" />
<div class="code_title" style="font-size: 18px;">java 代码</div>
<div class="dp-highlighter" style="font-size: 18px;">
<div class="bar" style="font-size: 18px;">&nbsp;</div>
<ol class="dp-j" start="1" style="font-size: 18px;">
    <li class="alt" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;"><span class="comment" style="font-size: 18px; line-height: 27px;">//&nbsp;产品A</span><span style="font-size: 18px; line-height: 27px;">&nbsp;&nbsp;</span></span></li>
    <li class="" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;"><span class="keyword" style="font-size: 18px; line-height: 27px;">public</span><span style="font-size: 18px; line-height: 27px;">&nbsp;</span><span class="keyword" style="font-size: 18px; line-height: 27px;">class</span><span style="font-size: 18px; line-height: 27px;">&nbsp;ProductA&nbsp;</span><span class="keyword" style="font-size: 18px; line-height: 27px;">implements</span><span style="font-size: 18px; line-height: 27px;"> Product {&nbsp;&nbsp;</span></span></li>
    <li class="alt" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;">&nbsp;&nbsp;......&nbsp;&nbsp;</span></li>
    <li class="" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;">}&nbsp;&nbsp;</span></li>
    <li class="alt" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;">&nbsp;&nbsp;</span></li>
    <li class="" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;"><span class="comment" style="font-size: 18px; line-height: 27px;">//&nbsp;产品B</span><span style="font-size: 18px; line-height: 27px;">&nbsp;&nbsp;</span></span></li>
    <li class="alt" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;"><span class="keyword" style="font-size: 18px; line-height: 27px;">public</span><span style="font-size: 18px; line-height: 27px;">&nbsp;</span><span class="keyword" style="font-size: 18px; line-height: 27px;">class</span><span style="font-size: 18px; line-height: 27px;">&nbsp;ProductB&nbsp;</span><span class="keyword" style="font-size: 18px; line-height: 27px;">implements</span><span style="font-size: 18px; line-height: 27px;"> Product {&nbsp;&nbsp;</span></span></li>
    <li class="" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;">&nbsp;&nbsp;......&nbsp;&nbsp;</span></li>
    <li class="alt" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;">}&nbsp;&nbsp;</span></li>
</ol>
</div>
<br style="font-size: 18px;" />
工厂<br style="font-size: 18px;" />
<div class="code_title" style="font-size: 18px;">java 代码</div>
<div class="dp-highlighter" style="font-size: 18px;">
<div class="bar" style="font-size: 18px;">&nbsp;</div>
<ol class="dp-j" start="1" style="font-size: 18px;">
    <li class="alt" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;"><span class="comment" style="font-size: 18px; line-height: 27px;">//&nbsp;工厂，用于创建具体的Product</span><span style="font-size: 18px; line-height: 27px;">&nbsp;&nbsp;</span></span></li>
    <li class="" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;"><span class="keyword" style="font-size: 18px; line-height: 27px;">public</span><span style="font-size: 18px; line-height: 27px;">&nbsp;</span><span class="keyword" style="font-size: 18px; line-height: 27px;">class</span><span style="font-size: 18px; line-height: 27px;">&nbsp;Factory&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class="" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;">&nbsp;&nbsp;<span class="comment" style="font-size: 18px; line-height: 27px;">//创建Product</span><span style="font-size: 18px; line-height: 27px;">&nbsp;&nbsp;</span></span></li>
    <li class="" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;">&nbsp; </span><span style="font-size: 18px; line-height: 27px;"><span class="keyword" style="font-size: 18px; line-height: 27px;">public</span><span style="font-size: 18px; line-height: 27px;"> </span></span><span style="font-size: 18px; line-height: 27px;"><span class="keyword" style="font-size: 18px; line-height: 27px;">static </span></span><span style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;">Product createProduct (String product) {<br />
    </span></span></li>
    <li class="" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;">&nbsp;&nbsp;&nbsp; <span class="keyword" style="font-size: 18px; line-height: 27px;">if</span><span style="font-size: 18px; line-height: 27px;">(&nbsp;product.equals(</span><span class="string" style="font-size: 18px; line-height: 27px;">&quot;A&quot;</span><span style="font-size: 18px; line-height: 27px;">)&nbsp;)&nbsp;&nbsp;</span></span></li>
    <li class="alt" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword" style="font-size: 18px; line-height: 27px;">return</span><span style="font-size: 18px; line-height: 27px;">&nbsp;</span><span class="keyword" style="font-size: 18px; line-height: 27px;">new</span><span style="font-size: 18px; line-height: 27px;">&nbsp;ProductA();&nbsp;&nbsp;</span></span></li>
    <li class="" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;">&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword" style="font-size: 18px; line-height: 27px;">else</span><span style="font-size: 18px; line-height: 27px;">&nbsp;</span><span class="keyword" style="font-size: 18px; line-height: 27px;">if</span><span style="font-size: 18px; line-height: 27px;">&nbsp;(&nbsp;product.equals(</span><span class="string" style="font-size: 18px; line-height: 27px;">&quot;B&quot;</span><span style="font-size: 18px; line-height: 27px;">)&nbsp;)&nbsp;&nbsp;</span></span></li>
    <li class="alt" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword" style="font-size: 18px; line-height: 27px;">return</span><span style="font-size: 18px; line-height: 27px;">&nbsp;</span><span class="keyword" style="font-size: 18px; line-height: 27px;">new</span><span style="font-size: 18px; line-height: 27px;">&nbsp;ProductB();&nbsp;&nbsp;</span></span></li>
    <li class="" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;">&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword" style="font-size: 18px; line-height: 27px;">else</span><span style="font-size: 18px; line-height: 27px;">&nbsp;&nbsp;&nbsp;</span></span></li>
    <li class="alt" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;......&nbsp;&nbsp;</span></li>
    <li class="" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;">&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="" style="font-size: 18px; line-height: 27px;"><span style="font-size: 18px; line-height: 27px;">}&nbsp;&nbsp;</span></li>
</ol>
</div>
<br style="font-size: 18px;" />
这样，我们创建对象的时候就不需要使用new了。<br style="font-size: 18px;" />
<br style="font-size: 18px;" />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span>Product&nbsp;proa&nbsp;=&nbsp;Factory.createProduct(</span><span class="string">&quot;A&quot;</span><span>);&nbsp;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>Product&nbsp;prob&nbsp;=&nbsp;Factory.createProduct(<span class="string">&quot;B&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<br style="font-size: 18px;" />
          <br/><br/>
          <span style="color:red;">
            <a href="http://smartfool.javaeye.com/blog/71937#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 17 Apr 2007 17:30:08 +0800</pubDate>
        <link>http://smartfool.javaeye.com/blog/71937</link>
        <guid>http://smartfool.javaeye.com/blog/71937</guid>
      </item>
      <item>
        <title>Builder - 创建者模式</title>
        <author>lintomny</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://smartfool.javaeye.com">lintomny</a>&nbsp;
          链接：<a href="http://smartfool.javaeye.com/blog/71175" style="color:red;">http://smartfool.javaeye.com/blog/71175</a>&nbsp;
          发表时间: 2007年04月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          对于Builder模式很简单，但是一直想不明白为什么要这么设计，为什么要向builder要Product而不是向知道建造过程的Director要。刚才google到一篇文章，总算清楚了。在这里转贴一下这位<a href="http://dev2dev.bea.com.cn/bbs/thread.jspa?forumID=125&amp;threadID=28019&amp;messageID=241582">richardluo的比喻</a>。<br />
<br />
<strong>简单地说，就好象我要一座房子住，可是我不知道怎么盖（简单的砌墙，层次较低），也不知道怎么样设计（建几个房间，几个门好看，层次较高），于是我需要找一帮<font color="#ff0000">民工，他们会砌墙</font>，还得找个<font color="#ff0000">设计师，他知道怎么设计</font>，我还要确保<font color="#ff0000">民工听设计师的领导</font>，而设计师本身也不干活，光是下命令，这里砌一堵墙，这里砌一扇门，这样民工开始建设，最后，我可以向民工要房子了。在这个过程中，<font color="#ff0000">设计师是什么也没有，除了他在脑子里的设计和命令，所以要房子也是跟民工要</font>，记住了！</strong><br />
<br />
以下是richardluo的代码，我根据他的思路加上了相应的注释。<br />
<br />
<strong>1，定义工人接口</strong>，就是能够完成建造房子任务的人的通用要求。<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j">
    <li class="alt"><span><span class="comment">// 工人接口，定义了各个工人所要进行的工所作。他们负责进行具体部件如窗户，地板的建造。</span></span> </li>
    <li class="alt"><span><span class="comment">// 同时因为房子是民工建的，因此建设完成后由他把房子递交回房主</span><span></span></span> </li>
    <li class=""><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">interface</span><span>&nbsp;Builder&nbsp;{&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;&nbsp;</span><span class="keyword">void</span><span>&nbsp;makeWindow();&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;&nbsp;</span><span class="keyword">void</span><span>&nbsp;makeFloor();&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;&nbsp;Room&nbsp;&nbsp;getRoom();&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>}&nbsp;&nbsp;</span> </li>
</ol>
</div>
<br />
<strong>2，定义设计师</strong>，他的职责是指挥房主指派给他的工人按照自己的设计意图建造房子。<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j">
    <li class="alt"><span><span class="comment">//&nbsp;设计师。他知道房子应该怎么设计，但他不会自己去建造，而是指挥民工去建造。</span><span>&nbsp;&nbsp;</span></span> </li>
    <li class=""><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Designer&nbsp;{&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;<span class="comment">//&nbsp;指挥民工进行工作</span><span>&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;order(Builder&nbsp;&nbsp;builder)&nbsp;{&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;builder.makeWindow();&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;builder.makeFloor();&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;}&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>}&nbsp;&nbsp;</span> </li>
</ol>
</div>
<br />
<strong>3，民工</strong>，他负责具体事物的实施。<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j">
    <li class="alt"><span><span class="comment">// 民工。负责进行具体部件如窗户，地板的建造。</span></span> </li>
    <li class="alt"><span><span class="comment">//同时因为房子是民工建的，因此建设完成后由他把房子递交回房主</span><span>&nbsp;&nbsp;</span></span> </li>
    <li class=""><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Mingong&nbsp;&nbsp;</span><span class="keyword">implements</span><span>&nbsp;Builder&nbsp;{&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;&nbsp;String&nbsp;window=</span><span class="string">&quot;&quot;</span><span>;&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;<span class="keyword">private</span><span>&nbsp;&nbsp;String&nbsp;floor=</span><span class="string">&quot;&quot;</span><span>;&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;&nbsp;</span><span class="keyword">void</span><span>&nbsp;makeWindow()&nbsp;{&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;window=<span class="keyword">new</span><span>&nbsp;String(</span><span class="string">&quot;window&quot;</span><span>);&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;}&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;&nbsp;</span><span class="keyword">void</span><span>&nbsp;makeFloor(){&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;floor=<span class="keyword">new</span><span>&nbsp;String(</span><span class="string">&quot;floor&quot;</span><span>);&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;}&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;<span class="comment">//&nbsp;回交房子给房主</span><span>&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;&nbsp;Room&nbsp;&nbsp;getRoom()&nbsp;{&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">if</span><span>((!window.equals(</span><span class="string">&quot;&quot;</span><span>))&amp;&amp;(!floor.equals(</span><span class="string">&quot;&quot;</span><span>)))&nbsp;{&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<span class="string">&quot;room&nbsp;ready!&quot;</span><span>);&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;</span><span class="keyword">new</span><span>&nbsp;Room();&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">else</span><span>&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">null</span><span>;&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;}&nbsp;&nbsp;</span> </li>
    <li class=""><span>}&nbsp;&nbsp;</span> </li>
</ol>
</div>
<br />
<strong>4，房主</strong>，就是雇人，收房。<br />
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j">
    <li class="alt"><span><span class="comment">//&nbsp;房主。房主的任务就是聘请一个民工，一个设计师，同时把民工给设计师指挥，督促设计师开展工作。最后从民工手上收房。&nbsp;&nbsp;</span><span>&nbsp;&nbsp;</span></span> </li>
    <li class=""><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;Client&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Builder&nbsp;mingong&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;Mingong();&nbsp;&nbsp;&nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Designer&nbsp;&nbsp;designer&nbsp;=&nbsp;<span class="keyword">new</span><span>&nbsp;&nbsp;Designer();&nbsp;&nbsp;&nbsp;&nbsp;</span></span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;designer.order(mingong);&nbsp;&nbsp;&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mingong.getRoom();&nbsp;&nbsp;&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;</span> </li>
    <li class=""><span>}&nbsp;&nbsp;&nbsp;</span> </li>
</ol>
</div>
<br />
好了，我觉得这样大概能说明白了。不知各位觉得如何呢？或者有更好的应用场景解释，敬请赐教。
          <br/><br/>
          <span style="color:red;">
            <a href="http://smartfool.javaeye.com/blog/71175#comments" style="color:red;">已有 <strong>9</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 14 Apr 2007 21:35:23 +0800</pubDate>
        <link>http://smartfool.javaeye.com/blog/71175</link>
        <guid>http://smartfool.javaeye.com/blog/71175</guid>
      </item>
      <item>
        <title>抽象工厂模式</title>
        <author>lintomny</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://smartfool.javaeye.com">lintomny</a>&nbsp;
          链接：<a href="http://smartfool.javaeye.com/blog/70952" style="color:red;">http://smartfool.javaeye.com/blog/70952</a>&nbsp;
          发表时间: 2007年04月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          试着总结一下学过的设计模式，就由创建型模式说起吧。<br />
<br />
<font size="4"><strong>意图</strong></font><em><br />
<strong>提供一个创建一系列相关活相互依赖对象的接口，而无需指定他们具体的类。</strong></em>(G4)<br />
<br />
<font size="4"><strong>任务</strong></font><br />
假设我们需要进行各种数据库操作，可是我们有很多的选择啊，JDBC，Hibernate，Ibatis等等。本来选择一个就OK了，可是变态的Boss为了炫耀我们的技术如何如何强大，竟说我们能够无成本地在这三个解决方案间切换。这下系统该怎么设计呢？<br />
或许你已经注意到<strong>每种解决方案自身都是完备而独立的</strong>，不错，这便是解决问题的切入点。提供一套解决方案