美文网首页
创建型-单例模式(Singleton Pattern)

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

作者: 木叶苍蓝 | 来源:发表于2022-12-13 09:55 被阅读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)
    

    相关文章

      网友评论

          本文标题:创建型-单例模式(Singleton Pattern)

          本文链接:https://www.haomeiwen.com/subject/kokhqdtx.html