创建型-单例模式(Singleton Pattern)

2022-12-13  本文已影响0人  木叶苍蓝

引入

一个类被设计出来,就意味着它具有某种行为(方法),属性(成员变量)。一般情况下,当我们想使用这个类时,会使用 new 关键字,这时候 jvm 会帮我们构造一个该类的实例。这么做比较耗资源。如果能在 jvm 启动时就 new 好。或者是某一次 new 好后,之后就 不用 new 了。这样就比较节省资源。
这就是单例模式要解决的问题。

单例实现步骤

要实现一个单例类,需要经过三个步骤:

  1. 私有化构造函数,目的是避免其它类可以创建这个类的对象;
  2. 在本类中创建唯一实例对象(因为构造函数私有化了,所以单例类的唯一实例对象只能在单例类里面创建),使用一个私有静态的成员变量保存。
  3. 对外提供一个公开的静态的函数供别人获取这个唯一的实例对象。

实例的两种实现方法:

  1. 饿汉式
    特定:在加载类的同时就创建了这个类的唯一实例;
    好处:可以保证这个类的实例的唯一性;
    弊端:如果只是使用这个类,但是暂时不需要它的对象,也会创建唯一实例,造成内存的浪费。
public class Single {
    // 1 私有化构造函数
    private Single() {}
    // 2 在本类中创建唯一实例对象,使用私有静态成员变量保存
    priave static Single ss = new Single();
    // 对外提供公开的静态的获取方法
    public static Single getInstance() {
        return ss;
    }
}

public class SingleDemo {
    priavte SingleDemo() {
        System.out.pintln("创建单例对象...");
    }
    private static SingleDemo ss = new SingleDemo();
    public static SingleDemo getInstance() {
        return ss;
    }
    // 单例类中,可以有其他属性和行为
    public staticvoid show() {
        Systemc.out.println("我是单例类中的一个静态函数")
    }
}

public class SingleTest {
    public static void main(String[] args) {
        // 调用单例类中的静态函数 show
        SingleDemo.show();
    }
}
  1. 懒汉式
    特点:在第一次调用获取实例的方法时才创建对象;
    好处:第一次调用获取实例的方法时才创建对象,可以避免内存的浪费;
    弊端:多线程环境下不能保证实例的唯一性;
public class Single2 {
    // 私有化构造函数
    private Single2() {}
    // 在本类中创建唯一实例对象,使用一个私有静态成员变量保存
    private static Single2 ss = null;
    // 对外提供一个公开静态的获取方法
    public static Single2 getInstance() {
        if (ss == null) {
            ss = new Single2();
        }
        return ss;
    }
}

public class SingleDemo2 {
    private SingleDemo2() {
        System.out.println("创建单例对象...")
    }
    private static SingleDemo2 ss = null;
    public static SingleDemo2 getInstance() {
        if (ss == null) {
            ss = new SingleDemo2();
        }
        return ss;
    }
    // 单例中,可以有其他属性和行为
    public static void show() {
        System.out.println("我是单例类SingleDemo2中的一个静态函数");
    }
}

public class SingleTest2 {
    public static void main(String[] args) {
        // 调用单例类中的静态函数 show
        SingleDemo2.show();
        SingleDemo2 s1 = SingleDemo2.getInstance();
        SingleDemo2 s2 = SingleDemo2.getInstance();
        System.out.println(s1);
        System.out.println(s2);
    }
}

单例模式的优点

  1. 严格控制对唯一的访问方式
  2. 仅有一个实例,可以节约系统资源

单例模式的缺点

  1. 单例模式没有抽象层,扩展比较困难
  2. 职责过重,即充当工厂角色,又充当产品角色
  3. 如果长期不使用,Java会自动回收,导致下次使用又重新实例化

单例模式的特点

  1. 有仅有一个单例类实例(无法通过反序列化重新构建对象)
  2. 构造函数私有化
  3. 通过静态方法或枚举获取单例类实例

示例代码

class Test:
    def __new__(cls):
        if not hasattr(cls, 'instance'):
            cls.instance = super(Test, cls).__new__(cls)
        return cls.instance

obj1 = Test()
obj2 = Test()
print(obj1 is obj2)

def singleton(cls):
    instances = {}
    def getinstance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return getinstance

@singleton
class MyClass:
    a = 1

c1 = MyClass()
c2 = MyClass()
print(c1 == c2)
上一篇 下一篇

猜你喜欢

热点阅读