首先,先来看看一个简单、特殊的创造物件的模式。
In software engineering, the singleton pattern is a software design pattern that restricts the instantiation of a class to one "single" instance. This is useful when exactly one object is needed to coordinate actions across the system.
Singleton (单例模式) 限制了一个类别只能建立唯一的实例。
这是什麽意思呢?如果我们先来看看一般的类别,譬如先前的 BaseballPlayer
,这里我们稍微简化一下,并且利用它产生两个实例 playerA 和 playerB
class BaseballPlayer {
constructor() {}
}
const playerA = new BaseballPlayer()
const playerB = new BaseballPlayer()
很明显的 playerA 和 playerB 是两个不同的东西
console.log(playerA === playerB) // false
那麽,我们要如何让一个类别只能建立一个唯一的实例,譬如
class BaseballPlayer {
// do something
}
const playerA = new BaseballPlayer()
const playerB = new BaseballPlayer()
然後让 playerA 和 playerB 都会拿到同样的实例
console.log(playerA === playerB) // true
在进入实作之前,先来看看这个模式想要解决什麽问题。
当使用者透过类别建立实例的时候,每个实例就是独立的个体,并可以各自执行各自的行为。
但如果我们想要「集中控管」使用者使用这个工具的行为,与其让使用者自己透过类别创造出各自新的工具,不如就想办法让使用者每次透过类别取得实例的时候,都取得「同一个工具」,也就会使用同一个工具。
对我们来说,我们只要控制这一个工具(实例),就等於控制了所有使用者手上的工具。
另一方面,如果有一个变数是需要让所有实例共享的的话,那麽也可以透过这个方式,让每一位使用者能够藉由取得同一个实例来操作同一个变数。
在系统当中,有些功能是高度共享的,如果这时候采用单例模式,就会便於管理。譬如 logger 或是 cache,不管是谁呼叫了这些实例或功能,都被集中管理,以避免不同实例各自操作所可能产生的 concurrent 问题
要实作单例模式,有一些不同的方法,这里使用「静态类别」的方法来实作。
静态类别的特性是,可以不用建立实例就可以取用其方法。所以这里我们利用这个特性,不让使用者建立实例 (e.g., new Gov()
),而是直接呼叫静态方法 getInstance
来取得实例。
所以在下面的程序码当中,如果使用者呼叫了 getInstance
但此时还没有任何实例,那麽就在这个方法内部建立新的实例。但如果实例已经存在,那麽就直接回传该实例。
class Gov {
private static instance: Gov
private constructor() { }
public static getInstance(): Gov {
if (!Gov.instance) {
Gov.instance = new Gov()
}
return Gov.instance
}
}
如此一来,就可以确保所有使用这个类别的使用者,都可以拿到同一个实例
const yourGov = Gov.getInstance()
const myGov = Gov.getInstance()
console.log(yourGov === myGov) // true
单例模式的优点是,藉由提供所有使用者同样的实例,让我们可以集中管理资料、操作行为。
但是缺点是,它违反了单一功能原则,因为他控制了
也因为集中管理,导致扩展性不佳。如果有任何的新需求进入,都必须更改这个类别当中的实作方式。另一方面,也可能会隐藏了它与其他类别的关系,因为对於使用者来说,只要直接取用实例就行,但如果要理解功能是如何实作,就必须进入这个类别的程序码查看,无法透过相对外显的继承、参数传递等方式来更快理解。
<<: 如何使用WYSIWYG Python GUI 设计工具快速设计出子视窗及产出程序码呢?
经过前两天的函示介绍相信大家对函式(Function)已经有一定程度的了解了吧, 那麽对於TS的函式...
09 - Time format 在专案中时常会有用到显示时间的地方,可能格式只有一种,但是会散落在...
Q1. 什麽是 python 反序列化 当我们希望在 Python 中保存一个物件(例如将机器学习训...
经过了两周的介绍,已经从古代慢慢走到了现代,也将环境准备的5566了,是时候该介绍我的工作核心:La...
偶尔会看到,往下滚,球就会跟着滚动的幅度以抛物线移动。 今天就来使用SVG的Path做做看! 其实是...