DAY 18:Singleton Pattern,致独一无二的你

什麽是 Singleton Pattern?

整个程序运作只会有此一个物件,不会创建第二个重复的物件

在实际情境中某些物件,比如连线 DB、与其他 service 长连线、取得环境 config,我们都希望可以整个运行环境「只有一个」,才不会造成资源的浪费,或者系统每个部分运行得到的值不同。

问题情境

取得连线 DB 的物件,并且整个系统不会重复创建导致浪费 DB 连线的资源。

解决方式

相关的 code 在Github - go-design-patterns

第一种方式(初始化即创建):在 import 模组的时候,将 db 透过init()创建dbInstance{}(init()function 有着程序 runtime 会先行运行的特性),此後只有GetInstance()这个公开方法可以取得dbInstance{},并无任何方法再创建dbInstance{}

优点:可以在初始化就创建 instance,不用等到呼叫才创建(第二种方式)
缺点:无法控制初始化的时间点,举例来说有可能「环境变数」套件都还没有初始化,db 就开始初始化了,导致读不到正确的环境变数

// db/db.go
package db

type DBInstance struct{}

var dbInstance *DBInstance

func init() {
	dbInstance = &DBInstance{}
}

func GetInstance() *DBInstance {
	return dbInstance
}
// main file
package main

import "DAY-18/db"

func main() {
	db.GetInstance()
}

为了解决缺点,所以许多专案会不以init()来初始化物件,而是任意一个公开方法来初始化:

// db-2/db-2.go file
package db

type DBInstance struct{}

var dbInstance *DBInstance

func InitDB() {
	dbInstance = &DBInstance{}
}

func GetInstance() *DBInstance {
	return dbInstance
}
// main file
package main

import db "DAY-18/db-2"

func main() {
	db.Init()
	db.GetInstance()
}

第二种方式(lazy 方式):在呼叫GetInstance()的时候会做检查,如果dbInstance{}不存在就创建,存在就回传现存的dbInstance{}

优点:可以在真的用到此物件时,才创建此物件,以节省记忆体,这即是 lazy 方式的优点
缺点:由於在使用物件时才会创建,所以第一次呼叫时需要创建会花较多的时间

package main

type DBInstance struct{}

var dbInstance *DBInstance

func GetInstance() *DBInstance {
	if dbInstance == nil {
		dbInstance = &DBInstance{}
	}
	return dbInstance
}

func main() {
	GetInstance()
}

如果觉得if dbInstance == nil的检查很麻烦的话,也可以用sync.Once{}来实作,sync.Once{}.Do(func)可以让 function 里的物件永远只执行一次,以达到 Singleton 的效果,里头适用 CAS 演算法来实作:

package main

import "sync"

type DBInstance struct{}

var (
	dbInstance *DBInstance
	once       = &sync.Once{}
)

func GetInstance() *DBInstance {
	once.Do(func() {
		dbInstance = &DBInstance{}
	})
	return dbInstance
}

func main() {
	GetInstance()
}

<<:  [神经机器翻译理论与实作] 你只需要专注力(II): 建立更专注的seq2seq模型

>>:  Day17 - 上架後台的商品列表页,今天只铺了 template

D17: 工程师太师了: 第9话

工程师太师了: 第9话 杂记: 最近在泡咖啡 被同事问说: 你一天都喝几杯咖啡阿? 我的回答:我大概...

Day.20 「初步认识 this,中央工厂式的自订物件~」 —— JavaSript 构造函式

如同学习函式一样!有时候我们会一直重复地做一件事, 当还是初学者的我们需要制作大量的个人资料物件时...

Python入门 Day 6 : # While True的用法

while 是循环结构(while一定要小写),while 後面搭配布林值(boolean)并用,F...

28. 表单验证

课程练习 串接 API 并可以呈现产品列表、加入购物车、购物车列表功能,表单送出前进行表单验证。 课...

android studio 30天学习笔记 -day 2 -icon

在这次的专案开发有用到vector asset,里面有一些可以应用在专案开发的向量图形,如以下图形:...