﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-小菜毛毛技术分享-随笔分类-设计模式</title><link>http://www.blogjava.net/caizh2009/category/43531.html</link><description>与大家共同成长</description><language>zh-cn</language><lastBuildDate>Thu, 04 Mar 2010 15:29:43 GMT</lastBuildDate><pubDate>Thu, 04 Mar 2010 15:29:43 GMT</pubDate><ttl>60</ttl><item><title>java工厂模式</title><link>http://www.blogjava.net/caizh2009/archive/2010/03/04/314518.html</link><dc:creator>小菜毛毛</dc:creator><author>小菜毛毛</author><pubDate>Thu, 04 Mar 2010 07:21:00 GMT</pubDate><guid>http://www.blogjava.net/caizh2009/archive/2010/03/04/314518.html</guid><wfw:comment>http://www.blogjava.net/caizh2009/comments/314518.html</wfw:comment><comments>http://www.blogjava.net/caizh2009/archive/2010/03/04/314518.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/caizh2009/comments/commentRss/314518.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/caizh2009/services/trackbacks/314518.html</trackback:ping><description><![CDATA[<table cellspacing="0" cellpadding="0" width="95%" align="center" border="0">
    <tbody>
        <tr>
            <td>
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td>
                        <table cellspacing="0" cellpadding="0" width="100%" border="0">
                            <tbody>
                                <tr>
                                    <td>&nbsp;</td>
                                </tr>
                                <tr>
                                    <td><strong>java工厂模式</strong></td>
                                </tr>
                                <tr>
                                    <td>
                                    <div align="right">[ 2009-2-6 16:15:00 | By: 孙大峰 ]</div>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                        <table cellspacing="0" cellpadding="0" width="100%" border="0">
                            <tbody>
                                <tr>
                                    <td height="3">&nbsp;</td>
                                </tr>
                            </tbody>
                        </table>
                        <table style="table-layout: fixed" cellspacing="0" cellpadding="0" width="100%" align="center" border="0">
                            <tbody>
                                <tr>
                                    <td><span><span id="ob_logd35622">
                                    <div style="display: inline; background: url(/Images/digg.gif) no-repeat left top; float: right; margin: 0px 10px 5px 0px; width: 45px; height: 55px; text-align: center">
                                    <div style="padding-right: 0px; padding-left: 0px; font-weight: 600; font-size: 18px; padding-bottom: 11px; width: 45px; color: #333; line-height: 1; padding-top: 10px; font-family: tahoma,Arial,Helvetica,sans-serif">6</div>
                                    <div style="padding-right: 0px; padding-left: 6px; padding-bottom: 0px; line-height: 1; padding-top: 3px; letter-spacing: 6px"><a style="font-size: 12px; line-height: 1" onclick="diggit(35622);" href="javascript:void(null)">推荐</a></div>
                                    </div>
                                    </span>
                                    <h2 style="margin: auto 0cm; line-height: 150%"></h2>
                                    <p style="line-height: 150%"><span style="line-height: 150%">一、引子<br />
                                    <span style="font-size: 10pt">话说十年前，有一个爆发户，他家有三辆汽车（<span style="font-size: 10pt">Benz</span>（奔驰）、<span style="font-size: 10pt">Bmw</span>（宝马）、<span style="font-size: 10pt">Audi</span>（奥迪）看来这人比较爱国，没有日本车），还雇了司机为他开车。不过，爆发户坐车时总是这样：上<span style="font-size: 10pt">Benz</span>车后跟司机说<span style="font-size: 10pt">"</span>开奔驰车！<span style="font-size: 10pt">"</span>，坐上<span style="font-size: 10pt">Bmw</span>后他说<span style="font-size: 10pt">"</span>开宝马车！<span style="font-size: 10pt">"</span>，坐上<span style="font-size: 10pt">Audi</span>后他说<span style="font-size: 10pt">"</span>开奥迪车！<span style="font-size: 10pt">"</span>。</span><span style="font-size: 10pt">你一定说：这人有病！直接说开车不就行了？！ </span><span style="font-size: 10pt">而当把这个爆发户的行为放到我们程序语言中来，我们发现<span style="font-size: 10pt">C</span>语言一直是通过这种方式来坐车的！</span><span style="font-size: 10pt">幸运的是，这种有病的现象在<span style="font-size: 10pt">OO</span>语言中可以避免了。下面以<span style="font-size: 10pt">Java</span>语言为基础来引入我们本文的主题：工厂模式！！</span></span></p>
                                    <div style="line-height: 150%" align="justify"><span style="font-size: 10pt; line-height: 150%">二、简介<span style="font-size: 10pt"><br />
                                    </span>工厂模式主要是为创建对象提供了接口。工厂模式按照《<span style="font-size: 10pt">Java</span>与模式》中的提法分为三类：<span style="font-size: 10pt"><br />
                                    1. </span>简单工厂模式<span style="font-size: 10pt">(Simple Factory) <br />
                                    2. </span>工厂方法模式<span style="font-size: 10pt">(Factory Method) <br />
                                    3. </span>抽象工厂模式<span style="font-size: 10pt">(Abstract Factory) <br />
                                    </span>这三种模式从上到下逐步抽象，并且更具一般性。还有一种分类法，就是将简单工厂模式看为工厂方法模式的一种特例，两个归为一类。下面是使用工厂模式的两种情况：<span style="font-size: 10pt"><br />
                                    1.</span>在编码时不能预见需要创建哪种类的实例。<span style="font-size: 10pt"><br />
                                    2.</span>系统不应依赖于产品类实例如何被创建、组合和表达的细节</span></div>
                                    <div style="line-height: 150%" align="justify"><span style="font-size: 10pt; line-height: 150%"><span style="font-size: 10pt"><br />
                                    &nbsp;</div>
                                    </span></span>
                                    <div style="line-height: 150%"><span style="font-size: 10pt; line-height: 150%">三、简单工厂模式<span style="font-size: 10pt"><br />
                                    </span>顾名思义，这个模式本身很简单，而且使用在业务较简单的情况下。<span style="font-size: 10pt"><br />
                                    </span>它由三种角色组成（关系见下面的类图）：<span style="font-size: 10pt"><br />
                                    </span>1、工厂类角色：这是本模式的核心，含有一定的商业逻辑和判断逻辑。在<span style="font-size: 10pt">java</span>中它往往由一个具体类实现。</span></div>
                                    <div style="line-height: 150%"><span style="font-size: 10pt; line-height: 150%">2、抽象产品角色：它一般是具体产品继承的父类或者实现的接口。在<span style="font-size: 10pt">java</span>中由接口或者抽象类来实现。</span></div>
                                    <div style="line-height: 150%"><span style="font-size: 10pt; line-height: 150%">3、具体产品角色：工厂类所创建的对象就是此角色的实例。在<span style="font-size: 10pt">java</span>中由一个具体类实现。<span style="font-size: 10pt"><br />
                                    </span></span><span style="font-size: 10pt; line-height: 150%"><img onmousewheel="return bbimg(this)" style="cursor: pointer" onclick="javascript:window.open(this.src);" height="209" src="http://blog.csai.cn/UploadFiles/2009-2/26825231.jpg" width="500" onload="rsimg(this,500)" resized="true"  alt="" /></span><span style="font-size: 10pt; line-height: 150%"><br />
                                    </span><span style="font-size: 10pt; line-height: 150%">那么简单工厂模式怎么用呢？我来举个例子吧，我想这个比讲一大段理论上的文字描述要容易理解的多！下面就来给那个暴发户治病<span style="font-size: 10pt">: P <br />
                                    </span>在使用了简单工厂模式后，现在暴发户只需要坐在车里对司机说句：<span style="font-size: 10pt">"</span>开车<span style="font-size: 10pt">"</span>就可以了。来看看怎么实现的：<span style="font-size: 10pt"><br />
                                    //</span>抽象产品角色<span style="font-size: 10pt"> <br />
                                    public interface Car{ <br />
                                    public void drive(); <br />
                                    }</span></span></div>
                                    <p style="line-height: 150%"><span style="font-size: 10pt; line-height: 150%">//</span><span style="font-size: 10pt; line-height: 150%">具体产品角色<span style="font-size: 10pt"> <br />
                                    public class Benz implements Car{ <br />
                                    public void drive() { <br />
                                    System.out.println("Driving Benz "); <br />
                                    } <br />
                                    }</span></span></p>
                                    <p style="line-height: 150%"><span style="font-size: 10pt; line-height: 150%">public class Bmw implements Car{ <br />
                                    public void drive() { <br />
                                    System.out.println("Driving Bmw "); <br />
                                    } <br />
                                    } <br />
                                    </span><span style="font-size: 10pt; line-height: 150%">。。。（奥迪我就不写了<span style="font-size: 10pt">:P</span>）</span></p>
                                    <p style="line-height: 150%"><span style="font-size: 10pt; line-height: 150%">//</span><span style="font-size: 10pt; line-height: 150%">工厂类角色<span style="font-size: 10pt"> <br />
                                    public class Driver{</span></span></p>
                                    <p style="line-height: 150%"><span style="font-size: 10pt; line-height: 150%">//</span><span style="font-size: 10pt; line-height: 150%">工厂方法<span style="font-size: 10pt"><br />
                                    //</span>注意 返回类型为抽象产品角色<span style="font-size: 10pt"> <br />
                                    public static Car driverCar(String s)throws Exception {</span></span></p>
                                    <p style="line-height: 150%"><span style="font-size: 10pt; line-height: 150%">//</span><span style="font-size: 10pt; line-height: 150%">判断逻辑，返回具体的产品角色给<span style="font-size: 10pt">Client <br />
                                    if(s.equalsIgnoreCase("Benz")) return new Benz(); <br />
                                    else if(s.equalsIgnoreCase("Bmw")) <br />
                                    return new Bmw();</span></span></p>
                                    <p style="line-height: 150%"><span style="font-size: 10pt; line-height: 150%">...... <br />
                                    else throw new Exception(); <br />
                                    </span><span style="font-size: 10pt; line-height: 150%">。。。</span></p>
                                    <div style="line-height: 150%"><span style="font-size: 10pt; line-height: 150%">//</span><span style="font-size: 10pt; line-height: 150%">欢迎暴发户出场<span style="font-size: 10pt">...... <br />
                                    public class Magnate{ <br />
                                    public static void main(String[] args){ <br />
                                    try{ <br />
                                    //</span>告诉司机我今天坐奔驰<span style="font-size: 10pt"><br />
                                    Car car = Driver.driverCar("benz"); <br />
                                    //</span>下命令：开车<span style="font-size: 10pt"><br />
                                    car.drive(); <br />
                                    </span>。。。<span style="font-size: 10pt"><br />
                                    </span>如果将所有的类放在一个文件中，请不要忘记只能有一个类被声明为<span style="font-size: 10pt">public</span>。</span> 程序中类之间的关系如下：</div>
                                    <div style="line-height: 150%"><img onmousewheel="return bbimg(this)" style="cursor: pointer" onclick="javascript:window.open(this.src);" height="205" src="http://blog.csai.cn/UploadFiles/2009-2/26294976.jpg" width="500" onload="rsimg(this,500)" resized="true"  alt="" /></div>
                                    <div><span style="font-size: 10pt; line-height: 150%">这便是简单工厂模式了。下面是其好处：</span></div>
                                    <div><span style="font-size: 10pt; line-height: 150%">首先，使用了简单工厂模式后，我们的程序不在<span style="font-size: 10pt">"</span>有病<span style="font-size: 10pt">"</span>，更加符合现实中的情况；而且客户端免除了直接创建产品对象的责任，而仅仅负责<span style="font-size: 10pt">"</span>消费<span style="font-size: 10pt">"</span>产品（正如暴发户所为）。<span style="font-size: 10pt"><br />
                                    </span>下面我们从开闭原则上来分析下简单工厂模式。当暴发户增加了一辆车的时候，只要符合抽象产品制定的合同，那么只要通知工厂类知道就可以被客户使用了。那么对于产品部分来说，它是符合开闭原则的<span style="font-size: 10pt">--</span>对扩展开放、对修改关闭；但是工厂部分好像不太理想，因为每增加一辆车，都要在工厂类中增加相应的商业逻辑和判断逻辑，这显自然是违背开闭原则的。<span style="font-size: 10pt"><br />
                                    </span>对于这样的工厂类（在我们的例子中是为司机师傅），我们称它为全能类或者上帝类。<span style="font-size: 10pt"><br />
                                    </span>我们举的例子是最简单的情况，而在实际应用中，很可能产品是一个多层次的树状结构。由于简单工厂模式中只有一个工厂类来对应这些产品，所以这可能会把我们的上帝类坏了，进而累坏了我们可爱的程序员<span style="font-size: 10pt">:( <br />
                                    </span>正如我前面提到的简单工厂模式适用于业务将简单的情况下。而对于复杂的业务环境可能不太适应阿。这就应该由工厂方法模式来出场了！！</span></div>
                                    <p style="line-height: 150%"><span style="font-size: 10pt; line-height: 150%">四、工厂方法模式<span style="font-size: 10pt"><br />
                                    </span>先来看下它的组成吧：<span style="font-size: 10pt"><br />
                                    </span>1、抽象工厂角色：这是工厂方法模式的核心，它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在<span style="font-size: 10pt">java</span>中它由抽象类或者接口来实现。<span style="font-size: 10pt"><br />
                                    </span>2、具体工厂角色：它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在<span style="font-size: 10pt">java</span>中它由具体的类来实现。<span style="font-size: 10pt"><br />
                                    </span>3、抽象产品角色：它是具体产品继承的父类或者是实现的接口。在<span style="font-size: 10pt">java</span>中一般有抽象类或者接口来实现。<span style="font-size: 10pt"><br />
                                    </span>4、具体产品角色：具体工厂角色所创建的对象就是此角色的实例。在<span style="font-size: 10pt">java</span>中由具体的类来实现。<span style="font-size: 10pt"><br />
                                    </span>来用类图来清晰的表示下的它们之间的关系：</span></p>
                                    <p style="line-height: 150%"><span style="font-size: 10pt; line-height: 150%"><img onmousewheel="return bbimg(this)" style="cursor: pointer" onclick="javascript:window.open(this.src);" height="211" src="http://blog.csai.cn/UploadFiles/2009-2/26950544.jpg" width="500" onload="rsimg(this,500)" resized="true"  alt="" /><br />
                                    </span></p>
                                    <p style="line-height: 150%"><span style="font-size: 10pt; line-height: 150%">我们还是老规矩使用一个完整的例子来看看工厂模式各个角色之间是如何来协调的。话说暴发户生意越做越大，自己的爱车也越来越多。这可苦了那位司机师傅了，什么车它都要记得，维护，都要经过他来使用！于是暴发户同情他说：看你跟我这么多年的份上，以后你不用这么辛苦了，我给你分配几个人手，你只管管好他们就行了！于是，工厂方法模式的管理出现了。代码如下：<span style="font-size: 10pt"><br />
                                    //</span>抽象产品角色，具体产品角色与简单工厂模式类似，只是变得复杂了些，这里略。<span style="font-size: 10pt"><br />
                                    //</span>抽象工厂角色<span style="font-size: 10pt"><br />
                                    public interface Driver{ <br />
                                    public Car driverCar(); <br />
                                    } <br />
                                    public class BenzDriver implements Driver{ <br />
                                    public Car driverCar(){ <br />
                                    return new Benz(); <br />
                                    } <br />
                                    } <br />
                                    public class BmwDriver implements Driver{ <br />
                                    public Car driverCar() { <br />
                                    return new Bmw(); <br />
                                    } <br />
                                    } <br />
                                    ......//</span>应该和具体产品形成对应关系，这里略<span style="font-size: 10pt">... <br />
                                    //</span>有请暴发户先生<span style="font-size: 10pt"> <br />
                                    public class Magnate <br />
                                    { <br />
                                    public static void main(String[] args) <br />
                                    { <br />
                                    try{ <br />
                                    Driver driver = new BenzDriver();</span></span></p>
                                    <p style="line-height: 150%"><span style="font-size: 10pt; line-height: 150%">Car car = driver.driverCar(); <br />
                                    car.drive(); <br />
                                    }catch(Exception e) <br />
                                    { } <br />
                                    } <br />
                                    } <br />
                                    </span><span style="font-size: 10pt; line-height: 150%">工厂方法使用一个抽象工厂角色作为核心来代替在简单工厂模式中使用具体类作为核心。让我们来看看工厂方法模式给我们带来了什么？使用开闭原则来分析下工厂方法模式。当有新的产品（即暴发户的汽车）产生时，只要按照抽象产品角色、抽象工厂角色提供的合同来生成，那么就可以被客户使用，而不必去修改任何已有的代码。看来，工厂方法模式是完全符合开闭原则的！<span style="font-size: 10pt"><br />
                                    </span>使用工厂方法模式足以应付我们可能遇到的大部分业务需求。但是当产品种类非常多时，就会出现大量的与之对应的工厂类，这不应该是我们所希望的。所以我建议在这种情况下使用简单工厂模式与工厂方法模式相结合的方式来减少工厂类：即对于产品树上类似的种类（一般是树的叶子中互为兄弟的）使用简单工厂模式来实现。<span style="font-size: 10pt"><br />
                                    </span>当然特殊的情况，就要特殊对待了：对于系统中存在不同的产品树，而且产品树上存在产品族，那么这种情况下就可能可以使用抽象工厂模式了。</span></p>
                                    <p style="line-height: 150%"><span style="font-size: 10pt; line-height: 150%">五、小结<span style="font-size: 10pt"><br />
                                    </span>让我们来看看简单工厂模式、工厂方法模式给我们的启迪：<span style="font-size: 10pt"><br />
                                    </span>如果不使用工厂模式来实现我们的例子，也许代码会减少很多<span style="font-size: 10pt">--</span>只需要实现已有的车，不使用多态。但是在可维护性上，可扩展性上是非常差的（你可以想象一下，添加一辆车后要牵动的类）。因此为了提高扩展性和维护性，多写些代码是值得的。</span></p>
                                    <p style="line-height: 150%"><span style="font-size: 10pt; line-height: 150%">六、抽象工厂模式<span style="font-size: 10pt"><br />
                                    </span>先来认识下什么是产品族：位于不同产品等级结构中，功能相关联的产品组成的家族。如果光看这句话就能清楚的理解这个概念，我不得不佩服你啊。还是让我们用一个例子来形象地说明一下吧。</span></p>
                                    <p style="line-height: 150%"><span style="font-size: 10pt; line-height: 150%">图中的<span style="font-size: 10pt">BmwCar</span>和<span style="font-size: 10pt">BenzCar</span>就是两个产品树（产品层次结构）；而如图所示的<span style="font-size: 10pt">BenzSportsCar</span>和<span style="font-size: 10pt">BmwSportsCar</span>就是一个产品族。他们都可以放到跑车家族中，因此功能有所关联。同理<span style="font-size: 10pt">BmwBussinessCar</span>和<span style="font-size: 10pt">BenzSportsCar</span>也是一个产品族。<span style="font-size: 10pt"><br />
                                    </span>回到抽象产品模式的话题上，可以这么说，它和工厂方法模式的区别就在于需要创建对象的复杂程度上。而且抽象工厂模式是三个里面最为抽象、最具一般性的。抽象工厂模式的用意为：给客户端提供一个接口，可以创建多个产品族中的产品对象。而且使用抽象工厂模式还要满足一下条件：<span style="font-size: 10pt"><br />
                                    1.</span>系统中有多个产品族，而系统一次只可能消费其中一族产品<span style="font-size: 10pt"><br />
                                    2.</span>同属于同一个产品族的产品以其使用。<span style="font-size: 10pt"><br />
                                    </span>来看看抽象工厂模式的各个角色（和工厂方法的如出一辙）：<span style="font-size: 10pt"><br />
                                    </span>抽象工厂角色：这是工厂方法模式的核心，它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类。在<span style="font-size: 10pt">java</span>中它由抽象类或者接口来实现。<span style="font-size: 10pt"><br />
                                    </span>具体工厂角色：它含有和具体业务逻辑有关的代码。由应用程序调用以创建对应的具体产品的对象。在<span style="font-size: 10pt">java</span>中它由具体的类来实现。<span style="font-size: 10pt"><br />
                                    </span>抽象产品角色：它是具体产品继承的父类或者是实现的接口。在<span style="font-size: 10pt">java</span>中一般有抽象类或者接口来实现。<span style="font-size: 10pt"><br />
                                    </span>具体产品角色：具体工厂角色所创建的对象就是此角色的实例。在<span style="font-size: 10pt">java</span>中由具体的类来实现。<span style="font-size: 10pt"><br />
                                    </span></span></p>
                                    <p style="line-height: 150%"><span style="font-size: 10pt; line-height: 150%">看过了前两个模式，对这个模式各个角色之间的协调情况应该心里有个数了，我就不举具体的例子了。只是一定要注意满足使用抽象工厂模式的条件哦，不然即使存在了多个产品树，也存在产品族，但是不能使用的。</span></p>
                                    </span></td>
                                </tr>
                            </tbody>
                        </table>
                        </td>
                    </tr>
                </tbody>
            </table>
            </td>
        </tr>
    </tbody>
</table>
 <img src ="http://www.blogjava.net/caizh2009/aggbug/314518.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/caizh2009/" target="_blank">小菜毛毛</a> 2010-03-04 15:21 <a href="http://www.blogjava.net/caizh2009/archive/2010/03/04/314518.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设计模式之Singleton(单态)</title><link>http://www.blogjava.net/caizh2009/archive/2010/01/11/309011.html</link><dc:creator>小菜毛毛</dc:creator><author>小菜毛毛</author><pubDate>Mon, 11 Jan 2010 05:44:00 GMT</pubDate><guid>http://www.blogjava.net/caizh2009/archive/2010/01/11/309011.html</guid><wfw:comment>http://www.blogjava.net/caizh2009/comments/309011.html</wfw:comment><comments>http://www.blogjava.net/caizh2009/archive/2010/01/11/309011.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/caizh2009/comments/commentRss/309011.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/caizh2009/services/trackbacks/309011.html</trackback:ping><description><![CDATA[<p><strong>单态定义</strong>:<br />
Singleton模式主要作用是保证在Java应用程序中，一个类Class只有一个实例存在。 </p>
<p>在很多操作中，比如建立目录 数据库连接都需要这样的单线程操作。</p>
<p>还有, singleton能够被状态化; 这样，多个单态类在一起就可以作为一个状态仓库一样向外提供服务，比如，你要论坛中的帖子计数器，每次浏览一次需要计数，单态类能否保持住这个计数，并且能synchronize的安全自动加1，如果你要把这个数字永久保存到数据库，你可以在不修改单态接口的情况下方便的做到。</p>
<p>另外方面，Singleton也能够被无状态化。提供工具性质的功能，<br />
<br />
Singleton模式就为我们提供了这样实现的可能。使用Singleton的好处还在于可以节省内存，因为它限制了实例的个数，有利于Java垃圾回收（garbage collection）。<br />
<br />
我们常常看到工厂模式中类装入器(class loader)中也用Singleton模式实现的,因为被装入的类实际也属于资源。<br />
</p>
<p><strong>如何使用?</strong><br />
一般Singleton模式通常有几种形式:</p>
<table cellspacing="3" cellpadding="3" width="100%" border="0">
    <tbody>
        <tr>
            <td bgcolor="#cccccc">
            <p>public class Singleton {</p>
            <p>　　private Singleton(){}</p>
            <p>　　//在自己内部定义自己一个实例，是不是很奇怪？<br />
            　　//注意这是private 只供内部调用</p>
            <p>　　private static Singleton instance = new Singleton();</p>
            <p>　　//这里提供了一个供外部访问本class的静态方法，可以直接访问　　<br />
            　　public static Singleton getInstance() {<br />
            　　　　return instance; 　　<br />
            　　 } <br />
            } </p>
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<p>第二种形式:</p>
<table cellspacing="3" cellpadding="3" width="100%" border="0">
    <tbody>
        <tr>
            <td bgcolor="#cccccc">public class Singleton {
            <p>　　private static Singleton instance = null;<br />
            <br />
            　　public static synchronized Singleton getInstance() {<br />
            <br />
            　　if (instance==null)<br />
            　　　　instance＝new Singleton();<br />
            　　return instance; 　　} </p>
            <p>} </p>
            <p>&nbsp;</p>
            </td>
        </tr>
    </tbody>
</table>
<p>使用Singleton.getInstance()可以访问单态类。</p>
<p>上面第二中形式是lazy initialization，也就是说第一次调用时初始Singleton，以后就不用再生成了。</p>
<p>注意到lazy initialization形式中的synchronized，这个synchronized很重要，如果没有synchronized，那么使用getInstance()是有可能得到多个Singleton实例。关于lazy initialization的Singleton有很多涉及double-checked locking (DCL)的讨论，有兴趣者进一步研究。</p>
<p>一般认为第一种形式要更加安全些。<br />
</p>
<p><strong>使用Singleton注意事项</strong>：<br />
有时在某些情况下，使用Singleton并不能达到Singleton的目的，如有多个Singleton对象同时被不同的类装入器装载；在EJB这样的分布式系统中使用也要注意这种情况，因为EJB是跨服务器，跨JVM的。</p>
<p>我们以SUN公司的宠物店源码(Pet Store 1.3.1)的ServiceLocator为例稍微分析一下：<br />
<br />
在Pet Store中ServiceLocator有两种，一个是EJB目录下；一个是WEB目录下，我们检查这两个ServiceLocator会发现内容差不多，都是提供EJB的查询定位服务，可是为什么要分开呢？仔细研究对这两种ServiceLocator才发现区别：在WEB中的ServiceLocator的采取Singleton模式，ServiceLocator属于资源定位，理所当然应该使用Singleton模式。但是在EJB中，Singleton模式已经失去作用，所以ServiceLocator才分成两种，一种面向WEB服务的，一种是面向EJB服务的。</p>
<p>Singleton模式看起来简单，使用方法也很方便，但是真正用好，是非常不容易，需要对Java的类 线程 内存等概念有相当的了解。</p>
<p>总之：如果你的应用基于容器，那么Singleton模式少用或者不用，可以使用相关替代技术。</p>
<p>&nbsp;</p>
<p>进一步深入可参考：</p>
<p><a href="http://www-106.ibm.com/developerworks/java/library/j-dcl.html?dwzone=java" target="_blank">Double-checked locking and the Singleton pattern</a></p>
<p><a href="http://www.javaworld.com/javaworld/jw-01-2001/jw-0112-singleton-p3.html#resources" target="_blank">When is a singleton not a singleton?</a></p>
<p><a href="http://www.jdon.com/jive/thread.jsp?forum=91&amp;thread=17578" target="_blank">Singleton是邪恶的</a></p>
<p><strong><a href="http://www.jdon.com/jivejdon/thread/33470.html" target="_blank">关于web应用的static变量</a></strong></p>
<p><a href="http://www.jdon.com/idea/jive/03003.htm" target="_blank">Jive中的单例模式</a></p>
<p><a href="http://www.jdon.com/jivejdon/tags/220" target="_blank">更多单例专题</a></p>
<p><a href="http://www.jdon.com/jivejdon/tags/819" target="_blank">更多本模式专题</a></p>
<p><a href="http://www.jdon.com/jivejdon/tags/819" target="_blank">更多线程安全专题</a></p>
<p><a href="http://www.jdon.com/jivejdon/tags/2229" target="_blank">更多同步或锁专题</a></p>
<p><a href="http://www.jdon.com/jivejdon/tags/326" target="_blank">更多对象生命周期专题</a></p>
<img src ="http://www.blogjava.net/caizh2009/aggbug/309011.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/caizh2009/" target="_blank">小菜毛毛</a> 2010-01-11 13:44 <a href="http://www.blogjava.net/caizh2009/archive/2010/01/11/309011.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>