【Java语言】Ja.2.2--浅谈设计模式(二)之单例模式

来源:互联网 发布:手机淘宝店装修 编辑:程序博客网 时间:2024/06/06 22:09

一、单例模式概述

      单例模式,笔者的理解就是单实例模式。怎么来说呢?打个比方,我们都知道一山不容二虎,一个山头出现了两只老虎那么必然会出现一些争斗,一些伤亡。那么在程序中会出现什么样的“虎”呢?比如:配置文件、工具类、线程池、缓存、日志对象等。如果创建了多个,那么就可能出现占用过多资源,数据读取不一致等等不是期望中的结果。
      那么保证程序中上述性质实例有且只有一个呢?这就要依靠单例模式了。

二、单例模式的饿汉式实现

      创建一个类Singleton.java,假设这个类的对象实例在程序中有且只能有一个。另外创建Test.java来模拟外部对Singleton类的访问。至此,我们有以下认识:

  • 在Test.java的main()方法中必然可以通过调用Singleton类的默认构造方法来生成多个不同的实例

      那么我们如何防止这种情况发生呢?一个有效的思路就是:

  1. 第一步:将Singleton类的构造方法声明为private,则在main()方法中就不能直接调用其构造方法了,也就不能产生任何实例了。
  2. 第二步:由于我们需要仅一个实例,所以可以在Singleton类里面实例化一个实例成员。虽然在类里面有一个实例成员,但是访问类成员得先实例化对象才能访问,这仿佛就像产生了死循环一般了。
  3. 第三步:通过把这个实例声明为static就可以通过类名来访问了。

示例代码如下:
1)Singleton.java:

package com.bebdong.Singleton_pattern;public class Singleton {    private  Singleton(){    }    static Singleton instance=new Singleton();}

2)Test.java:

package com.bebdong.Singleton_pattern;public class Test {    public static void main(String[] args) {        Singleton s1=Singleton.instance;        Singleton s2=Singleton.instance;        if(s1==s1)            System.out.println("s1和s2是同一实例");        if(s1!=s2)            System.out.println("s1和s2不是同一实例");    }}

3)运行结果:
这里写图片描述

      但是这样做的话就违背了面向对象编程中的安全原则,为此我们需要将实例做访问控制即声明为private,这样就不能直接通过类名来访问了。从而需要添加一个静态方法来获取这个静态实例。如下:

Singleton.java:

package com.bebdong.Singleton_pattern;public class Singleton {    private  Singleton(){    }    private static Singleton instance=new Singleton();    public static Singleton getInstance(){        return instance;    }}

      当然相应的,外部访问代码也应做修改:通过调用这个公有的静态方法来获取唯一的实例。运行程序,仍然可以知道s1和s2为同一实例。

三、单例模式的懒汉式实现

       我们还是三步走:

  1. 将构造方法私有化,不允许外部直接创建对象。
  2. 声明类的唯一实例,以private static 修饰。
  3. 提供一个用户获取实例的方法,用public static 修饰。

注:和饿汉模式的区别就在于实例化对象的位置,具体参见代码。

Singleton.java:

package com.bebdong.Singleton_pattern;public class Singleton {    private  Singleton(){    }    private static Singleton instance;  //只声明,不实例化    public static Singleton getInstance(){        if(instance==null){             //用一个判断条件确定需不需要实例化            instance=new Singleton();        }        return instance;    }}

      Test.java做相应修改,运行可以发现仍然为同一个实例。

四、饿汉模式和懒汉模式的区别

      根据上述饿汉式和懒汉式在实现上的细微差别,可以得出如下结论:

  1. 由于饿汉式实现在声明唯一对象的时候已经初始化,故而当类加载的时候将同时实例化这个唯一的对象。具有类加载慢,获取对象快的特点。
  2. 而懒汉模式在类加载的时候不会同时实例化这个唯一的对象,它只有当外部第一次时才实例化。具有类加载快,运行时获取对象的速度比较慢的特点。
  3. 第三个区别可能隐藏得比较深:饿汉模式是线程安全的,而懒汉模式不是线程安全的。
0 0
原创粉丝点击