上級者向け!TypeScriptでシングルトンパターンを使いこなすテクニック
TypeScriptでシングルトンパターンを実装するには、いくつかの方法があります。
コンストラクタをprivateにする
これは最も簡単な方法です。クラスのコンストラクタをprivateにすることで、外部からインスタンスを作成することができなくなります。
class Singleton {
private constructor() {}
private static instance: Singleton;
public static getInstance(): Singleton {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
const singleton1 = Singleton.getInstance();
const singleton2 = Singleton.getInstance();
console.log(singleton1 === singleton2); // true
クラス変数を使う
この方法は、クラス変数を使ってインスタンスを保存します。
class Singleton {
private static instance: Singleton | null = null;
public static getInstance(): Singleton {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
const singleton1 = Singleton.getInstance();
const singleton2 = Singleton.getInstance();
console.log(singleton1 === singleton2); // true
モジュールを使う
export class Singleton {
private constructor() {}
private static instance: Singleton | null = null;
public static getInstance(): Singleton {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
const singleton1 = Singleton.getInstance();
const singleton2 = Singleton.getInstance();
console.log(singleton1 === singleton2); // true
シンボルを使う
const singletonSymbol = Symbol();
export class Singleton {
private constructor() {}
private static instance: Singleton | null = null;
public static getInstance(): Singleton {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
const singleton1 = Singleton.getInstance();
const singleton2 = Singleton.getInstance();
console.log(singleton1 === singleton2); // true
シングルトンパターンを使うメリット
- オブジェクトの数が少なくなる
- オブジェクトの状態を管理しやすくなる
- オブジェクトへのアクセスが一元化される
- テストが難しい
- 柔軟性に欠ける
- 依存関係の注入が難しい
class Singleton {
private constructor() {}
private static instance: Singleton;
public static getInstance(): Singleton {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
const singleton1 = Singleton.getInstance();
const singleton2 = Singleton.getInstance();
console.log(singleton1 === singleton2); // true
class Singleton {
private static instance: Singleton | null = null;
public static getInstance(): Singleton {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
const singleton1 = Singleton.getInstance();
const singleton2 = Singleton.getInstance();
console.log(singleton1 === singleton2); // true
export class Singleton {
private constructor() {}
private static instance: Singleton | null = null;
public static getInstance(): Singleton {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
const singleton1 = Singleton.getInstance();
const singleton2 = Singleton.getInstance();
console.log(singleton1 === singleton2); // true
const singletonSymbol = Symbol();
export class Singleton {
private constructor() {}
private static instance: Singleton | null = null;
public static getInstance(): Singleton {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
const singleton1 = Singleton.getInstance();
const singleton2 = Singleton.getInstance();
console.log(singleton1 === singleton2); // true
シングルトンパターンを実装する他の方法
遅延初期化
この方法は、インスタンスが実際に必要になるまで作成しないというものです。
class Singleton {
private constructor() {}
private static instance: Singleton | null = null;
public static getInstance(): Singleton {
if (!Singleton.instance) {
// ここでインスタンスを作成する
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
const singleton1 = Singleton.getInstance();
const singleton2 = Singleton.getInstance();
console.log(singleton1 === singleton2); // true
ファクトリー関数を使う
この方法は、ファクトリー関数を使ってインスタンスを作成するというものです。
function createSingleton(): Singleton {
if (!Singleton.instance) {
// ここでインスタンスを作成する
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
const singleton1 = createSingleton();
const singleton2 = createSingleton();
console.log(singleton1 === singleton2); // true
デコレータを使う
この方法は、デコレータを使ってシングルトンパターンを実装するというものです。
function singleton(constructor: Function) {
return class Singleton {
private static instance: Singleton | null = null;
public static getInstance(): Singleton {
if (!Singleton.instance) {
// ここでインスタンスを作成する
Singleton.instance = new constructor();
}
return Singleton.instance;
}
};
}
@singleton
class MySingleton {
// ...
}
const singleton1 = MySingleton.getInstance();
const singleton2 = MySingleton.getInstance();
console.log(singleton1 === singleton2); // true
singleton typescript