Java——单例设计模式

时间:2022-07-25
本文章向大家介绍Java——单例设计模式,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Java中有几个重要的设计模式,工厂设计模式、代理设计模式、单例设计模式,前几个在之前的博客中讲解过基本程序套路,本次讲解单例设计模式。

1、单例设计模式

现在有这样一个类,非常简单,只是当个引子。

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

此时SingleIton存在一个无参构造方法,因为自动生成的。构造方法一般是使用public声明,但是也可以使用private声明。

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Singleton inst = new Singleton();
        inst.print();
    }
}
class Singleton{
    private Singleton() { //构造方法私有了
    }

    public void print(){
        System.out.println("hello");
    }
}

以上代码是错误的,因为此时构造方法被私有化了,无法从外部进行构造方法 的调用。现在要求构造方法、print()方法不修改的前提下,通过一些适当的SingleIton变化让外部类可以得到SingleIton类的实例化对象,并且调用print()方法。分析如下:

分析一:程序构造方法使用了private,对于private的特点,只能够在本类中进行访问,那么可以在本类中准备一个实例化对象。

class Singleton{
    Singleton instance = new Singleton();
    private Singleton() { //构造方法私有了
    }

    public void print(){
        System.out.println("hello");
    }
}

分析二:此时内部声明的instance为普通属性,其只有在实例化对象后可以调用,目前外部无法实例化对象,所以可以使用static,其不受实例化对象的影响。

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Singleton inst = null;
        inst = Singleton.instance;
        inst.print();
    }
}
class Singleton{
    static Singleton instance = new Singleton();
    private Singleton() { //构造方法私有了
    }

    public void print(){
        System.out.println("hello");
    }
}

分析三:根据我们前面所学,只要是类中出现的属性,就必须使用private进行封装,以上代码中的instance属性需要进行封装,但是封装后,就必须通过方法访问,此时需要访问的static属性,并且类无法直接在外部产生实例化对象,所以可以再编写一个static方法。

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Singleton inst = null;
        inst = Singleton.getInstance();
        inst.print();
    }
}
class Singleton{
    private static Singleton instance = new Singleton();
    private Singleton() { //构造方法私有了
    }
    public static Singleton getInstance(){
        return instance;
    }
    public void print(){
        System.out.println("hello");
    }
}

分析四:以上代码很繁杂,最终目的实际上就是外部使用实例化对象调用方法,那么这种设计的意义是什么?

        Singleton instA = null;
        Singleton instB = null;
        Singleton instC = null;
        instA = Singleton.getInstance();
        instB = Singleton.getInstance();
        instC = Singleton.getInstance();
        instA.print();

以上代码中实例化了三个对象,我们进行内存关系分析:

不管外部有多少个对象声明,最终所能产生的实例化对象只有一个。本程序限制了实例化对象的产生,只维持了一个。

分析五:代码存在缺陷

为了包装整个代码操作过程中,只有唯一的一个实例化对象,且不可更改,可以使用final声明:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Singleton instA = null;
        instA = Singleton.getInstance();
        instA.print();
    }
}
class Singleton{
    private static final Singleton INSTANCE = new Singleton();
    private Singleton() { //构造方法私有了
    }
    public static Singleton getInstance(){
        return INSTANCE;
    }
    public void print(){
        System.out.println("hello");
    }
}

以上就是单例设计模式,程序的主要特点:构造方法私有化,外部无法产生新的实例化对象,只能通过类提供的static方法,取得唯一一个对象的引用。

对于单例设计模式,有两类,饿汉式(以上代码就是)、懒汉式。

  • 饿汉式:无论程序中是否有对象需要使用此类,此类对象都要实例化好;
  • 懒汉式:在第一次使用的时候才进行实例化。

【举例】:观察懒汉式

class Singleton{
    private static Singleton instance;
    private Singleton() { //构造方法私有了
    }
    public static Singleton getInstance(){
        if(instance == null){
            instance = new Singleton(); //需要的时候进行实例化
        }
        return instance;
    }
    public void print(){
        System.out.println("hello");
    }
}

这两个分类只是一个小概念,关键还是将之前的单例设计模式编写熟练。

2、多例设计模式

本质一样,构造方法私有化,内部产生实例化对象,只不过单例设计模式只产生一个,多例设计模式可以产生有限的多个。例如:描述性别的类,只能有两个。

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Sex sex = Sex.getInstance(Sex.MALE_CH);
        System.out.println(sex);
    }
}
class Sex{
    public static final int MALE_CH =1;
    public static final int FEMALE_CH =2;
    private static final Sex MALE = new Sex("男");
    private static final Sex FEMALE = new Sex("女");
    private String title;
    private Sex(String title) {
        this.title = title;
    }
    public static Sex getInstance(int ch){
        switch (ch){
            case MALE_CH:
                return MALE;
            case FEMALE_CH:
                return FEMALE;
                default:
                    return null;
        }
    }
    public String toString(){
        return this.title;
    }
}

多例设计模式只是单例设计模式的衍生,本质上没有区别。

3、总结

1)对于单例设计模式、多例设计模式,需要理解设计的出发点:限制对象的产生;

2)程序的基本结构必须记住,与开发 理解结构设计直接联系,很重要。