设计模式---单例模式(java+python版本)

本文介绍了单例模式的概念、实现方式及其优缺点。包括饿汉式、懒汉式、枚举式等多种实现方法,并提供了Python和Java语言的具体示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

最近就是想再学设计模式,所以稍微总结下。这篇我们主要是说单例模式,这对于开发来说基本是用过,下面虽然有好几种实现,但一般还是饿汉式的实现方式工作中最常使用。如果可以确保此类是全局可⽤不需要做懒加载,那么直接创建并给外部调⽤即可, 但如果是很多的类,需要触发⼀定的条件后才显示,那么⼀定要⽤懒加载。 线程的安全上可以按需选择。

概念

单例模式是指在内存中只会创建且仅创建一次对象的设计模式在程序中多次使用同一个对象且作用相同时,为了防止频繁地创建对象使得内存飙升,单例模式可以让程序仅在内存中创建一个对象,让所有需要调用的地方都共享这一单例对象。

类型

  1. 饿汉式:在类加载时已经创建好该单例对象,等待被程序使用
  2. 懒汉式:在真正需要使用对象时才去创建该单例类对象
  3. *枚举式: 与饿汉式一样在加载时已经创建。可以防止利用反射强行构建单例对象,而且可以在枚举类对象被反序列化的时候,保证反序列的返回结果是同一对象(此方法是:effactive java作者写的)

代码实现

饿汉式

python实现饿汉式

# 饿汉式
class Singleton(object):
    # 重写创建实例的__new__方法
    def __new__(cls):
        # 如果类没有实例属性,进行实例化,否则返回实例
        if not hasattr(cls, 'instance'):
            cls.instance = super(Singleton, cls).__new__(cls)
        return cls.instance
 

java实现饿汉式

// 饿汉式
public class Singleton{
    
    private static final Singleton singleton = new Singleton();
    
    private Singleton(){}
    
    public static Singleton getInstance() {
        return singleton;
    }
}

懒汉式 

python实现懒汉式

# 懒汉式
class Singleton(object):
    __instance = None
    def __init__(self):
        if not self.__instance:
            print('调用__init__, 实例未创建')
        else:
            print('调用__init__,实例已经创建过了:', __instance)

    @classmethod
    def get_instance(cls):
        # 调用get_instance类方法的时候才会生成Singleton实例
        if not cls.__instance:
            cls.__instance = Singleton()
        return cls.__instance

java懒汉式

// 懒汉式---这种方式消耗资源多,不建议使用
public class Singleton {
    private Singleton() {}  //私有构造函数
    //单例对象 volatile -->阻止变量访问前后的指令重排,保证指令执行的顺序
    private volatile static Singleton instance = null;  
    //双重检测机制 -->两次因为线程执行很快,不能保证只实例化一次
    public static Singleton getInstance() {
         if (instance == null) {    
         // 保证了线程安全  
         synchronized (Singleton.class){  
           if (instance == null) {     
             instance = new Singleton();
                }
             }
          }
          return instance;
      }
}

 枚举式

// 枚举
// 这种是java作者之一写的,是目前最好的,防止利用反射强行构建单例对象,而且可以在枚举类对象被反序列化的时候,保证反序列的返回结果是同一对象
public enum SingletonEnum {
    INSTANCE;
}

其他实现方式

python-基于metaclass方式实现

import threading

class SingletonType(type):
    _instance_lock = threading.Lock()
    def __call__(cls, *args, **kwargs):
        if not hasattr(cls, "_instance"):
            with SingletonType._instance_lock:
                if not hasattr(cls, "_instance"):
                    cls._instance = super(SingletonType,cls).__call__(*args, **kwargs)
        return cls._instance

class example(metaclass=SingletonType):
    def __init__(self,name):
        self.name = name

python-类(classmethod)

class Singleton(object):

    def __init__(self):
        pass

    @classmethod
    def instance(cls, *args, **kwargs):
        if not hasattr(Singleton, "_instance"):
            Singleton._instance = Singleton(*args, **kwargs)
        return Singleton._instance

python-装饰器

def singleton(cls, *args, **kw):  
    instances = {}  
    def _singleton():  
        if cls not in instances:  
            instances[cls] = cls(*args, **kw)  
        return instances[cls]  
    return _singleton  
 
@singleton  
class Example(object):  
    def __init__(self):  
        pass 

java-静态内部类

public class Singleton {
    private static class LazyHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
    private Singleton (){}
    public static Singleton getInstance() {
        return LazyHolder.INSTANCE;
    }
}

优缺点

优点

  1. 在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例
  2. 避免对资源的多重占用(比如写文件操作,数据库的连接等)

缺点

没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化

 

学习链接

什么是单例模式?

单例模式——面试官的“利剑”

菜鸟-单例模式(菜鸟说的也很详细= = ||)

 

既然无处可逃,不如喜悦。既然没有净土,不如静心。既然没有如愿,不如释然。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木子林_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值