浅识JAVA设计模式——单例设计模式

版权声明:本文为 Codeagles 原创文章,可以随意转载,但必须在明确位置注明出处!!!

单例设计模式

  • 什么是单例设计模式?
    所谓的单例设计指的是一个类只允许产生一个实例化对象。
    我们来看单例设计模式是如何一步一步演化过来的。

Talk is cheap, show me the code.

public class SingletonTest {

    public static void main(String[] args) {
        Singleton s= null;
        s=new Singleton();
        s.print();
    }

}
class Singleton{
    public Singleton(){}
    public void print(){
        System.out.println("Hello World");
    }
}

对于这段代码,很简单都不陌生,就是创建Singleton类,然后在另一个类中去实例化对象调用print方法,最后输出Hello World。原因是因为当我们在SingletonTest中实例化了对象的时候调用了Singleton类中的无参的构造方法,接下来结果就不足为奇了。

public class SingletonTest {
    
    public static void main(String[] args) {
        Singleton s= null;
        s=new Singleton();//报错
        s.print();
    }

}
class Singleton{
    private Singleton(){}//私有构造方法
    public void print(){
        System.out.println("Hello World");
    }
}

那么对于上述代码,进行改造,将构造方法的public改为private,那么上述代码就会报错,因为实例化的时候,构造方法被私有,表示该类不能被外部进行实例化对象,那么如何解决这个问题,我们继续看改造代码。

public class SingletonTest {
    
    public static void main(String[] args) {
        Singleton s= null;
        s=Singleton.instance;//②
        s.print();
    }

}
class Singleton{

    static Singleton instance = new Singleton();//①
    private Singleton(){}//私有构造方法
    public void print(){
        System.out.println("Hello World");
    }
}

为了解决外部不能实例化对象的问题,那么就在内部进行实例化对象,加上Singleton instance = new Singleton();那么就可以解决这个问题,但是在内部是解决了,外部依然无法调用print方法啊,因为外部没有对象,所以我们想到用static关键字,例如①所示,然后在SingletonTest中如②直接类.对象来创建新对象,再去调用print方法,问题搞定了。

那么新的问题来了,以上虽然取得了Singleton类的实例化对象,但是对于类中的属性应该用private进行封装,想要访问封装属性知道需要提供getter方法,那么我们需要在①的前面加上private static Singleton instance = new Singleton();不过此时访问的是static属性,并且这个类无法在外部进行实例化对象创建,所以再提供一个static方法,因为static方法不受实例化控制。那么改造的代码如下:

public class SingletonTest {
    
    public static void main(String[] args) {
        public static void main(String[] args) {
        Singleton s= null;
        s=Singleton.getInstance();//获取实例化对象
        //s1=Singleton.getInstance();//获取实例化对象
        //s2=Singleton.getInstance();//获取实例化对象
        s.print();
    }
    }

}
class Singleton{

    private static Singleton instance = new Singleton();//加上private
    //提供static方法,用来获取实例化对象
    public static Singleton getInstance(){
        return instance;
    }
    private Singleton(){}//私有构造方法
    public void print(){
        System.out.println("Hello World");
    }
}

对于上述代码,在Singleton类中,提供了获取实例化对象的静态方法,也将属性进行了私有化,那么在SingletonTest中无论获取多少个对象,实际上都是同一个对象,因为类加载的时候已经实例化了一次对象,这就是单例设计模式。

扩展

对于单例设计模式,还有两种类型:

  • 饿汉式
  • 懒汉式

饿汉式

既然是饿汉式,我们就要在整体之中,只能有一个实例化对象,所以一般在原基础上还会为其增加final关键字。这个没有什么分析的问题。

class Singleton{

    private final static Singleton INSTANCE = new Singleton();//加上final
    //提供static方法,用来获取实例化对象
    public static Singleton getInstance(){
        return INSTANCE;
    }
    private Singleton(){}//私有构造方法
    public void print(){
        System.out.println("Hello World");
    }
}

对于代码改造就是一点,其他的都不变,这就是饿汉式。

懒汉式

所谓懒汉式,是指第一次去使用Singleton类对象的时候,才会为其进行实例化处理操作。

class Singleton{

    private static Singleton instance;//不需要再去实例化
    public static Singleton getInstance(){
        if(instance==null){//表示此时还没有实例化对象
            instance=new Singleton();
        }
        return instance;
    }
    private  Singleton(){}//私有构造方法
    public void print(){
        System.out.println("Hello World");
    }
}

这就是懒汉式,当然这个设计模式在后续多线程等部分会有性能问题,以后我们在进行讨论。

对于单例的使用场景,比如windows中的回收站就是一个例子,不管是在C,D,E盘那个盘符中,都会有一个隐藏的回收站文件夹,将文件放入到该文件夹后,再回到桌面上打开回收站发现文件在里面,说明不论在哪,整个系统只有一个回收站,这就是典型的单例设计。

以上就是单例设计模式,一步一步在最基础的代码中,演化出来的。

你可能感兴趣的:(浅识JAVA设计模式——单例设计模式)