1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

TypeScriptでデザインパターンを考えてみる(Singleton編)

Last updated at Posted at 2023-07-14

この記事は?

オライリー社から出版されている「HeadFirst デザインパターン」を読んだ内容を
理解の整理のためTypeScriptで実装してみる内容です。(定期で載せれる様がんばる)

対象となるデザインパターン

Singletonパターン

コードで書いてみる

TSで実装してみると以下のようになります。

index.ts
// 必ず一つのインスタンスだけを生成するクラス
class Singleton {
  private static instance: Singleton; // クラス変数を定義して、それを一意のインスタンスとして保持する
  name: string;

  // コンストラクターをprivateで定義するのがポイント。内部からだけ初期化できるようになる
  private constructor(name: string) {
    this.name = name;
  }

  // Singletonインスタンスを呼び出すためのメソッド
  // このメソッドがコンストラクターとしてコールされる
  static getInstance(name: string): Singleton {
    if (Singleton.instance === undefined) Singleton.instance = new Singleton(name);

    return Singleton.instance;
  }
}

以上です。名前の通り、実装もシンプルですね。
実際に一つのインスタンスが保障されているか確認してみます。

検証用コード.ts
const first = Singleton.getInstance("first");
console.log(first.name); // => first

const second = Singleton.getInstance("second");
console.log(second.name); // => first

console.log(first === second); // => true

ちゃんと動作している様ですね。

使い所

正直、自分が仕事で触っているサービスでは、Singletonを使用したいケースは思いつきませんでした。
なので、どのような時にこのデザインパターンが使われるのかあまり想像できなかったので、ググってみました。

以下のサイトの記事がわかりやすかったので、転載させていただきます。

こちらのサイトによると、Singletonはむやみやたらに使うべきではなく、使うべきかどうか判断を行った方が良さそうですね。(あたりまえのことですが、大事な事です。)

一般的には以下のような機能を実装する際にSingletonが使用されるみたいです。

  • ロギング
  • キャッシュ管理
  • スレッドプール管理
  • データベース接続ドライバ
  • ソケット制御ドライバ

一覧で見てみると、使い所のイメージが少し湧いてきそうですね。

Singletonを使う際の注意点

参考書では、マルチスレッドを使用した実装の際は注意するよう、紹介されていました。
マルチスレッドを使用した場合、Singletonでも一意性を担保できない場合があるようです。

参考書では対応方法として、
非同期処理を同期的に動作させる synchronized (JSでいうところの Promise のような機能) や、二重チェックロッキングを行う volatile (調べたところJSではこのような機能はなさそう)などの方法が紹介されていました。
(参考書のコードは全てJavaで実装されてます)

余談: JavaScriptでのマルチスレッド

JavaScriptの実行環境は主にブラウザかnodeが想定されます。
基本的には両者ともシングルスレッドで動作するようですが、共にマルチスレッドで動かす方法もあるみたいです。

  • ブラウザ: WebWorkersなど
  • node: clusterなど

しかしJavaScriptにはvolatileのような二重チェックロッキング機能はないので、Javaのようにコードで安全性を担保するのは難しそうです。(自分の調べた範囲では。)
なので結論としては

「マルチスレッドは使用しない」
or
「マルチスレッドを使用するときはスレッドセーフな実装をするよう気を付ける」

を心がける必要があるのかなと思います。

まとめ

名前の通りシンプルなデザインパターンで、目的と実装がイメージしやすい印象でした。
仕事で使うシーンはあんまりないかもしれませんが、こういったデザインパターンがある、ということを知っておくことがリテラシー的な意味で大事かなと思います。

また、Singletonを通して、マルチスレッドの仕組みや理解が深まったのが、個人的には一番の成果だったかな、と感じました。

次回は「Commandパターン」だ。継続でがんばるぞー。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?