プログラミングマガジン

プログラミングを中心にIT技術をできるだけわかりやすくまとめます。

  • ホーム
  • デザインパターン
  • 【GoFのデザインパターン】「Singleton(シングルトン)」ってどんなパターン?、注…
 
 
     
  • サーバー言語  
    • Python
    • Ruby
    • PHP
    • SQL
  •  
  • インフラ  
       
    • AWS
    •  
    • 基本
    • Git
  • Web
       
    • Web開発
    • JavaScript
    • Vue.js
    • React
  •  
  • 設計  
       
    • 実装設計
    • DB設計
  • 問い合わせ
  

【GoFのデザインパターン】「Singleton(シングルトン)」ってどんなパターン?、注意点なども。

05.12

  • miyabisan2
  • コメントを書く

この記事は2分で読めます

「Singleton」ってどんなパターン?

あるクラスのオブジェクトを一つだけ作り、各クラスで共有したい場合に使うパターンです。

メリット

「システムの起動から、終了まで、そのクラスのオブジェクトが一つしか存在しないこと」を保証できます。

例えば、マルチスレッドのプログラムだと、どちらのスレッドが唯一のインスタンスを持つスレッドなのか判定させるのが難しかったりしますしね。

使用例

  • JavaのRuntimeクラス等は、JVM上で一つのオブジェクトしか存在してはいけない。
  • アプリケーション全体を監視するタイマークラス

具体的に実装してみる。

SingletonTest.java(シングルトンで実装したクラス)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package Singleton;
 
/**
* Singletonのテストクラスです。
*/
public class SingletonTest {
 
//インスタンスをクラス変数に格納して、グローバルな存在にする。
static SingletonTest onlyInstance;
 
//privateにすることで、不用意にnewされることを防ぐ。
private SingletonTest() {
//何もしない。
}
 
static SingletonTest getInstance() {
if(onlyInstance == null) {
onlyInstance = new SingletonTest();
}
return onlyInstance;
}
 
}

getInstanceで呼び出し元に、インスタンスを返していますが、その際の変数はクラス変数(static変数)にして、システムで共通の変数としています。

自分自身のインスタンスをグローバルなstaticメンバとして持ちます。

コンストラクタをprivateにすることで、不用意にnewされることを防いでいます。

コンストラクタがprivateなので、自分自身のクラスからしかnewができません。(なので、getInstanceというstaticメソッドを作ってその中で自分自身をnewするように実装します。)

Main.java(呼び出すクラス)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package Singleton;
 
public class Main {
 
public static void main(String[] args) {
 
//1回目の呼び出し。
SingletonTest test1 = SingletonTest.getInstance();
 
//2回目の呼び出し。
SingletonTest test2 = SingletonTest.getInstance();
 
System.out.println(test1);
System.out.println(test2);
 
}
 
}

実行結果

2回のインスタンス生成メソッド(getInstance)の、呼び出しを行っているのにも関わらず、下記のように同じ「クラス名@英数字」になっていることから、同じインスタンスが生成されていることがわかります。

注意点1:複数スレッド時の問題

複数スレッドで同時にプログラムが実行されるときに2回newされる可能性がある点です。

対策

1度目に実行しようとした際にメソッドをロックしてしまうことです。

Javaなら

synchronizedキーワードを使う。

C#など

ロックオブジェクトを使う

ロックオブジェクトとlock構文を使います。マルチスレッドの場合に非同期で実行しようとするプログラムを同期化してくれます。

staticクラスを使う(C#2.0より)

こうするだけでstaticのクラスを実装できます。なおその場合メンバ変数やメソッドも全てstaticにする必要があります。

getInstanceだったり、lockだったりと余計な構文を覚える必要がないので非常に楽です。新しくプログラムを作成するときは積極的に活用していくと良いでしょう。

その場合のシングルトンの判断方法としては「コンストラクタがprivateになっているか」で判断すると良いでしょう。

staticクラスの注意点

継承が書けないことです。なので拡張性はないクラスになるのでそこだけは注意しましょう。その場合だけは普通のシングルトン実装をするようにしましょう。

(ただ、基本的にシングルトンのクラスを継承で作りたいと思ったことはないので基本的には全てstaticクラスで実装すると良いでしょう。)

JavaScriptなら

以下のように記述するだけでシングルトンになります。

1
export default new クラス名();

その他方法

初期化子を使う方法もあります。

注意点2: テストコード時の問題

テストコード1を実行したときにシングルトンだと同じインスタンスを使い回すので連続で実行すると違う結果になる場合があります。

対策

  • テストの間にインスタンスを初期化する処理を実行する。baseクラスとして継承させても良いかもです。
スポンサーリンク
  • 2018 05.12
  • miyabisan2
  • コメントを書く
  • Java, オブジェクト指向, デザインパターン
  • Tweets Twitter
  • このエントリーをはてなブックマークに追加
  • LINEで送る

関連記事

  1. 2018 06.20

    【Struts】画面遷移させる。

  2. 2018 04.22

    【Webアプリ】設計の基本(Java)

  3. 2022 04.03

    【オブジェクト指向】「リスコフの置換原則」について

  4. 2018 05.04

    【Maven】プロジェクトの作成方法

  5. 2018 06.17

    【Java】「POJO」とは?

  6. 2018 05.01

    【Java】+演算子、StringBuilder、StringBufferの違い(実際に測ってみた。)、文字列系の型

  • コメント ( 0 )
  • トラックバック ( 0 )
  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

返信をキャンセルする。

【GoFのデザインパターン】「Builder」ってどん…

【GoFのデザインパターン】「Adapter」ってどん…

RETURN TOP

著者プロフィール

エンジニア歴10年で過去に業務系、Webデザイン、インフラ系なども経験あります。現在はWeb系でフロントエンド開発中心です。

詳細なプロフィールはこちら

スポンサーリンク

カテゴリー

  • Android
  • AngularJS
  • API
  • AWS
  • C++
  • CSS
  • cursor
  • C言語
  • DDD
  • DevOps
  • Django
  • Docker
  • Figma
  • Git
  • GitLab
  • GraphQL
  • gRPC
  • Hasura
  • Java
  • JavaScript
  • Kubernetes
  • Laravel
  • linux
  • MySQL
  • Next.js
  • nginx
  • Node.js
  • NoSQL
  • Nuxt.js
  • Oracle
  • PHP
  • Python
  • React
  • Redux
  • Rspec
  • Ruby
  • Ruby on Rails
  • Sass
  • Spring Framework
  • SQL
  • TypeScript
  • Unity
  • Vue.js
  • Webサービス開発
  • Webデザイン
  • Web技術
  • インフラ
  • オブジェクト指向
  • システム開発
  • セキュリティ
  • その他
  • データベース
  • デザインパターン
  • テスト
  • ネットワーク
  • プログラミング全般
  • マイクロサービス
  • マイクロソフト系技術
  • マルチメディア
  • リファクタリング
  • 副業
  • 未分類
  • 業務知識
  • 生成AI
  • 設計
  • 関数型言語
RETURN TOP

Copyright ©  プログラミングマガジン | プライバシーポリシー