大话设计模式--Singleton(单例模式)

 

 

大话设计模式--Singleton(单例模式)

——Angel

 

目录

1.什么是Singleton – 单例模式... 1

2. 非Singleton例子... 2

3. Singleton例子... 5

4.为什么需要Singleton. 8

 

 

说明:

1>    开发工具Eclipse

2>    开发平台Window Xp

3>    有问题可联系本人 QQ412887952

 

1.什么是Singleton – 单例模式

我有6个漂亮的老婆,她们的老公都是我,我就是我们家的singleton,她们只要说道老公,都是指同一个人,那就是我。

(哎,哪有那么好的事呀,除非做梦了。)

   笑够了就得回来了。我们的目标还是学习,当然咱们学习讲究乐中学,学中乐,最终是快乐成长。我们回头看看这个笑话:

【我】就是程序中的一个【类】

【我的6个老婆】就是程序中的“我”的6个实例。(平时我们都是用new 实例化对象,当然用这种方式构造出来的对象,那就不是我同一个对象了,回到例子的话,也就是说,我的6个漂亮老婆就不是我了,是其他对应的6个人了,嘎嘎,啊啊,我不要这样呀,我要我的老婆呀。)

【同一个人,都是我】就是程序用的同一个对象,从内存来看的话就是地址相等。(等下我们用程序证明:我们获取的对象都是同一个对象。)

 

 

从上面可以看出所谓的单例:就是只有一个实例。单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

更多资料:http://baike.baidu.com/view/1859857.htm

 

 

2. Singleton例子

   在学习Singleton模式之前,我们先看看以前普通的java类。

现在让我们一起创建一个  “我的类”,类名为Angel (这个是我的QQ昵称,所以这么命名呀。),在此类中提供一个方法,比如 loveMyWife (“我爱我的6个老婆“)

Angel.java代码如下:

package singleton_001;

 

 

/**

 * 自己的一个类

 * @author Administrator

 *

 */

public class Angel {

    public void loveMyWife(){

       System.out.println("我爱我的老婆,我的6个老婆都是我的呀,不允许公用!");

    }

}

说明:这个类没有太多的知识点,仅是普普通通的一个类,类中有一个简单的方法,方法中输出一句话。

我们在写一个测试类,来测试我们的程序,类名为 TestAngel.java

TestAngel.java代码如下:

package singleton_001;

 

public class TestAngel {

   

    /** main方法启动程序*/

    public static void main(String[] args) {

       Angel myWife = new Angel();//假设这个是真正的老婆

       Angel myWife1 = new Angel();// 我的第一个老婆

       Angel myWife2 = new Angel();// 我的第二个老婆

       Angel myWife3 = new Angel();// 我的第三个老婆

       Angel myWife4 = new Angel();// 我的第四个老婆

       Angel myWife5 = new Angel();// 我的第五个老婆

       Angel myWife6 = new Angel();// 我的第六个老婆

       /*我们通过比较对象的对象是否相同,来判定是否同一个实例*/

       if(myWife == myWife1){//相等的时候

           System.out.println("老婆1说:老公我爱你,你永远是我的好老公");

           System.out.println("我说:都是我的好老婆....");

          

       }else {//不相等的时候

           System.out.println("老婆1说:你不是我的老公,走开了呀!");

           System.out.println("我说:啊,不要,我要你做我的老婆");

       }

      

       if(myWife == myWife2){//相等的时候

           System.out.println("老婆2说:老公我爱你,你永远是我的好老公");

           System.out.println("我说:都是我的好老婆....");

          

       }else {//不相等的时候

           System.out.println("老婆2说:你不是我的老公,走开了呀!");

           System.out.println("我说:啊,不要,我要你做我的老婆");

       }

      

       if(myWife == myWife3){//相等的时候

           System.out.println("老婆3说:老公我爱你,你永远是我的好老公");

           System.out.println("我说:都是我的好老婆....");

          

       }else {//不相等的时候

           System.out.println("老婆3说:你不是我的老公,走开了呀!");

           System.out.println("我说:啊,不要,我要你做我的老婆");

       }

      

      

       if(myWife == myWife4){//相等的时候

           System.out.println("老婆4说:老公我爱你,你永远是我的好老公");

           System.out.println("我说:都是我的好老婆....");

          

       }else {//不相等的时候

           System.out.println("老婆4说:你不是我的老公,走开了呀!");

           System.out.println("我说:啊,不要,我要你做我的老婆");

       }

      

       if(myWife == myWife5){//相等的时候

           System.out.println("老婆5说:老公我爱你,你永远是我的好老公");

           System.out.println("我说:都是我的好老婆....");

          

       }else {//不相等的时候

           System.out.println("老婆5说:你不是我的老公,走开了呀!");

           System.out.println("我说:啊,不要,我要你做我的老婆");

       }

      

       if(myWife == myWife6){//相等的时候

           System.out.println("老婆6说:老公我爱你,你永远是我的好老公");

           System.out.println("我说:都是我的好老婆....");

          

       }else {//不相等的时候

           System.out.println("老婆6说:你不是我的老公,走开了呀!");

           System.out.println("我说:啊,不要,我要你做我的老婆");

       }

    }

}

说明:这个类看是代码特别多,但是提取出重要代码的话,就一句话:

new if (初始化对象,判断对象是否是同一个对象。)

 

运行代码,结果如下:

老婆1说:你不是我的老公,走开了呀!

我说:啊,不要,我要你做我的老婆

老婆2说:你不是我的老公,走开了呀!

我说:啊,不要,我要你做我的老婆

老婆3说:你不是我的老公,走开了呀!

我说:啊,不要,我要你做我的老婆

老婆4说:你不是我的老公,走开了呀!

我说:啊,不要,我要你做我的老婆

老婆5说:你不是我的老公,走开了呀!

我说:啊,不要,我要你做我的老婆

老婆6说:你不是我的老公,走开了呀!

我说:啊,不要,我要你做我的老婆

 

结果分析:

通过代码我们发现,这种方式的对象都是不相等的。(嘎嘎,没有一个是我的老婆呀,不做我老婆做我小妾也可以呀。)

 

3. Single例子

   接下来我们看看单例的例子。我们来修改下我们之前的代码.

观察我们的代码,我们发现我们的每一个实例都是通过new的方式进行生产的,我们知道通过new产生的对象就会在计算机内存开辟一个内存空间,所以肯定不是同一个对象。现在我们要让实例化的对象都是一样的,也就是说这个对象的产生,我们自己控制,不允许他人用new的方式进行构造,所以第一步我们需要把无参构造方法给屏蔽掉,也就是重写无参构造方法,将该方法改成私有的。改完之后,我们会发现我们根本就得不到我们的实例,那怎么办呢,我们通过一个静态方法来构造对象。代码体现如下:

Angel.java代码:

package singleton_002;

 

 

/**

 * 自己的一个类

 * @author Administrator

 *

 */

public class Angel {

   

    /*该类对象,用静态变量,确保只在内存开辟一个内存空间*/

    private static Angel instance;

   

    /**将该类的构造方法屏蔽*/

    private Angel(){};

   

    /**提供获取该类的实例*/

    public static Angel getInstance(){

       if(instance == null){

           synchronized (Angel.class) {//锁住当前类,防止两个线程同时访问

              instance = new Angel();

           }

       }

       return instance;

    }

   

    public void loveMyWife(){

       System.out.println("我爱我的老婆,我的6个老婆都是我的呀,不允许公用!");

    }

}

TestAngel.java代码:

package singleton_002;

 

import java.io.ObjectInputStream.GetField;

 

public class TestAngel {

   

    /** main方法启动程序*/

    public static void main(String[] args) {

       Angel myWife = Angel.getInstance();//假设这个是真正的老婆

       Angel myWife1 = Angel.getInstance();// 我的第一个老婆

       Angel myWife2 = Angel.getInstance();// 我的第二个老婆

       Angel myWife3 = Angel.getInstance();// 我的第三个老婆

       Angel myWife4 = Angel.getInstance();// 我的第四个老婆

       Angel myWife5 = Angel.getInstance();// 我的第五个老婆

       Angel myWife6 = Angel.getInstance();// 我的第六个老婆

       /*我们通过比较对象的对象是否相同,来判定是否同一个实例*/

       if(myWife == myWife1){//相等的时候

           System.out.println("老婆1说:老公我爱你,你永远是我的好老公");

           System.out.println("我说:都是我的好老婆....");

          

       }else {//不相等的时候

           System.out.println("老婆1说:你不是我的老公,走开了呀!");

           System.out.println("我说:啊,不要,我要你做我的老婆");

       }

      

       if(myWife == myWife2){//相等的时候

           System.out.println("老婆2说:老公我爱你,你永远是我的好老公");

           System.out.println("我说:都是我的好老婆....");

          

       }else {//不相等的时候

           System.out.println("老婆2说:你不是我的老公,走开了呀!");

           System.out.println("我说:啊,不要,我要你做我的老婆");

       }

      

       if(myWife == myWife3){//相等的时候

           System.out.println("老婆3说:老公我爱你,你永远是我的好老公");

           System.out.println("我说:都是我的好老婆....");

          

       }else {//不相等的时候

           System.out.println("老婆3说:你不是我的老公,走开了呀!");

           System.out.println("我说:啊,不要,我要你做我的老婆");

       }

      

      

       if(myWife == myWife4){//相等的时候

           System.out.println("老婆4说:老公我爱你,你永远是我的好老公");

           System.out.println("我说:都是我的好老婆....");

          

       }else {//不相等的时候

           System.out.println("老婆4说:你不是我的老公,走开了呀!");

           System.out.println("我说:啊,不要,我要你做我的老婆");

       }

      

       if(myWife == myWife5){//相等的时候

           System.out.println("老婆5说:老公我爱你,你永远是我的好老公");

           System.out.println("我说:都是我的好老婆....");

          

       }else {//不相等的时候

           System.out.println("老婆5说:你不是我的老公,走开了呀!");

           System.out.println("我说:啊,不要,我要你做我的老婆");

       }

      

       if(myWife == myWife6){//相等的时候

           System.out.println("老婆6说:老公我爱你,你永远是我的好老公");

           System.out.println("我说:都是我的好老婆....");

          

       }else {//不相等的时候

           System.out.println("老婆6说:你不是我的老公,走开了呀!");

           System.out.println("我说:啊,不要,我要你做我的老婆");

       }

       

    }

}

运行代码结果如下:

老婆1说:老公我爱你,你永远是我的好老公

我说:都是我的好老婆....

老婆2说:老公我爱你,你永远是我的好老公

我说:都是我的好老婆....

老婆3说:老公我爱你,你永远是我的好老公

我说:都是我的好老婆....

老婆4说:老公我爱你,你永远是我的好老公

我说:都是我的好老婆....

老婆5说:老公我爱你,你永远是我的好老公

我说:都是我的好老婆....

老婆6说:老公我爱你,你永远是我的好老公

我说:都是我的好老婆....

结果分析:

从上面代码我们发现,我们所构造的每一个对象都是同一个实例。

(嘎嘎,都是我的老婆呀。)

 

4.为什么需要Singleton

   刚接触单例的人肯定都会有和我相同的疑问:为什么我们需要单例。有人肯定会说:单例可以减少内存空间的开辟。这个说法没有错,但是这不是单例存在的实质。单例存在的实质主要是:

数据共享——可以在不建立直接关联的条件下,让多个不相关的两个线程或者进程之间实现通信。比如,数据库连接池的设计一般采用单例模式,数据库连接是一种数据库资源;控制资源的使用,通过线程同步来控制资源的并发访问;控制实例产生的数量,达到节约资源的目的。

 

5. Singleton使用场景

简而言之,就是任何只需要一个实例的地方.例如,窗口管理器,假脱机打印设备,数据库连接池。具体应用中,配置信息类,管理类,控制类,门面类,代理类通常被设计为单例类.

1)读取配置文件的类:比如你的工程需要读取配置文件,一般情况下你会写个配置文件的类,而这个类在整个工程里只需要new一次,所有调用者都是用同一个实例,那么这个类就可以采用单例模式。

2)管理器的类:一些管理器的类都是单例的,所有跟管理有关的操做都要调用管理器来进行,管理器不能出现多个,所以要单例,避免管理混乱。

3)日志操作类:你如果多个实例打开同一个文件写日志,那肯定是不行的(当然,如果你非要多个实例之间做同步,打开文件,写,关,然后下一个实例,这种,那性能就不行了)。

4)配置信息类:负责配置文件的解析,通常被设计为单例类。

5)管理类:如连接池管理类,通常被设计为单例类。

6)控制类:如strutsActionServlet类,也是单例类。

7)门面类:说到门面类,就不能不提门面(Facade)模式。客户端与多个子系统的通信必须通过一个统一的门面(Facade)对象进行,这就是门面模式。这个统一的门面(Facade)对象就是门面类。在门面模式中,通常只需要一个门面类,并且此门面类只有一个实例,换言之它是一个单例类。但这不是绝对的。

8)代理类:在Jive中,使用代理模式实现权限访问的入口,就采用了单例模式。

 

 

 

你可能感兴趣的:(单例模式,Singleton)