[设计模式]创建型模式-单例模式

简介: [设计模式]创建型模式-单例模式

前言

单例模式是最简单的一种模式。在Go中,单例模式指的是全局只有一个实例,并且它负责创建自己的对象。单例模式有减少内存和系统资源开销、防止多个实例产生冲突等优点。

因为单例模式保证了实例的全局唯一性,并且只被初始化一次,所以比较适合全局共享一个实例,且只需要被初始化一次的场景,例如数据库实例、全局配置、全局任务池等。

单例模式又分为饿汉方式和懒汉方式。饿汉方式是指全局的单例实例在包被加载时创建,而懒汉方式指全局的单例实例在第一次被使用时创建。其中懒汉方式是开源项目中使用最多的方式。

示例代码

Go

懒汉方式的缺点是非并发安全,实际使用中一般加锁,或者使用sync.Once

package singleton  
  
import "sync"  
  
type Singleton interface {  
    foo()  
}  
  
type singleton struct{}  
  
func (s singleton) foo() {}  
  
var (  
    instance *singleton  
    once     sync.Once  
)  
  
func GetInstance() Singleton {  
    once.Do(func() {  
       instance = &singleton{}  
    })  
  
    return instance  
}

单元测试

package singleton  
  
import (  
    "sync"  
    "testing")  
  
const parCount = 100  
  
func TestSingleton(t *testing.T) {  
    ins1 := GetInstance()  
    ins2 := GetInstance()  
    if ins1 != ins2 {  
       t.Fatal("instance is not equal")  
    }  
}  
  
func TestParallelSingleton(t *testing.T) {  
    start := make(chan struct{})  
    wg := sync.WaitGroup{}  
    wg.Add(parCount)  
  
    instance := [parCount]Singleton{}  
    for i := 0; i < parCount; i++ {  
       go func(index int) {  
          <-start  
          instance[index] = GetInstance()  
          wg.Done()  
       }(i)  
    }  
    close(start)  
    wg.Wait()  
    for i := 1; i < parCount; i++ {  
       if instance[i] != instance[i-1] {  
          t.Fatal("instance is not equal")  
       }  
    }  
}

Python

python的包是天然的单例模式,只要放到单独的包中,import时就是引用的单例。

如果要在一个包内使用设计模式,也有以下几种方式。

使用函数装饰器实现单例

def singleton(cls):  
    _instance = {}  
  
    def inner():  
        if cls not in _instance:  
            _instance[cls] = cls()  
        return _instance[cls]  
  
    return inner  
  
  
@singleton  
class MyCls:  
    def __init__(self):  
        pass  
  
  
if __name__ == "__main__":  
    a = MyCls()  
    b = MyCls()  
    print(id(a) == id(b))  # 输出结果应为 True

使用类装饰器实现单例

class Singleton:  
    def __init__(self, cls):  
        self._cls = cls  
        self._instance = {}  
  
    def __call__(self):  
        if self._cls not in self._instance:  
            self._instance[self._cls] = self._cls()  
        return self._instance[self._cls]  
  
  
@Singleton  
class MyCls:  
    def __init__(self):  
        pass  
  
  
if __name__ == "__main__":  
    a = MyCls()  
    b = MyCls()  
    print(id(a) == id(b))  # 输出结果应该是True

参考

相关文章
|
10天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
10天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是"将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。创建型模式分为5种:单例模式、工厂方法模式抽象工厂式、原型模式、建造者模式。
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
2月前
|
设计模式 架构师 Java
设计模式之 5 大创建型模式,万字长文深剖 ,近 30 张图解!
设计模式是写出优秀程序的保障,是让面向对象保持结构良好的秘诀,与架构能力与阅读源码的能力息息相关,本文深剖设计模式之 5 大创建型模式。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
设计模式之 5 大创建型模式,万字长文深剖 ,近 30 张图解!
|
24天前
|
设计模式 存储 前端开发
前端必须掌握的设计模式——单例模式
单例模式是一种简单的创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点。适用于窗口对象、登录弹窗等场景,优点包括易于维护、访问和低消耗,但也有安全隐患、可能形成巨石对象及扩展性差等缺点。文中展示了JavaScript和TypeScript的实现方法。
|
30天前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
25 2
|
2月前
|
设计模式 Java 数据库连接
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
40 4
|
2月前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
|
2月前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
|
2月前
|
设计模式 存储 数据库连接
PHP中的设计模式:单例模式的深入理解与应用
【10月更文挑战第22天】 在软件开发中,设计模式是解决特定问题的通用解决方案。本文将通过通俗易懂的语言和实例,深入探讨PHP中单例模式的概念、实现方法及其在实际开发中的应用,帮助读者更好地理解和运用这一重要的设计模式。
24 1
|
2月前
|
设计模式 安全 Java
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
Kotlin教程笔记(57) - 改良设计模式 - 单例模式
28 0