LINEスタンプ制作代行サービス・LINEスタンプの作り方!

お電話でのお問い合わせ:03-6869-8600

stampfactory大百科事典

Singleton パターン

Singleton パターン(シングルトン・パターン)とは、オブジェクト指向のコンピュータプログラムにおける、デザインパターンの1つである。GoF(Gang of Four; 4人のギャングたち)によって定義された。Singleton パターンを用いると、そのクラスのインスタンスが1つしか生成されないことを保証することができる。ロケールやLook&Feelなど、絶対にアプリケーション全体で統一しなければならない仕組みの実装に使用される。Singleton パターンの一般的なクラス図を示す。このクラス図で注目すべきことは以下の3点である。クラス図内にあるアンダーラインは、その項目がクラス変数あるいはクラス関数であることを意味している。以下にSingleton パターンを用いたクラスのJavaによる例を示す。このクラスにおいて、コンストラクタはcodice_2で定義されているため、他のクラスによって、codice_3クラスのインスタンスを生成することはできない。このクラスのインスタンスを生成したいときは、codice_1メソッドを利用することになるが、このメソッドは最初に呼び出されたときにだけインスタンスを生成し、2回目以降に呼び出されたときは最初に生成したインスタンスを返すように作られている。そのため、プログラム中にcodice_3クラスのインスタンスが1つしか存在しないことが保証される。codice_1メソッドがcodice_7に指定されているのは、複数のスレッドからほぼ同時に呼び出された際に複数のインスタンスが生成されてしまう危険性をなくすためである。Java における一般的な Singleton パターンの記述は上述した通りであるが、この方法は同期化コストが高い。そこでdouble-checked lockingというイディオム が考えられたが、「アウトオブオーダー書き込み」を許すJavaプラットフォームのメモリー・モデルにより同期化に失敗する(言うまでもないが、この最適化による副作用は Java だけのものではない)。この問題を克服しようとするとコードが肥大化しコストがかかる。そこで現在では以下のように static フィールドを用いることが推奨されている。これによりコストは改善される。同期化は行われないが、static フィールドの初期化はそのクラスが呼び出される最初の一回しか行われないため、何回codice_1メソッドを呼んでもスレッドアンセーフを心配する必要はなくなるだけでなく、コストパフォーマンスも非常に高い。ただしこの場合、Singletonクラスがロードされたときに初期化されるのであって、codice_1が初めて呼ばれたときではない。このことはプログラマーの意図しないタイミングで初期化が始まってしまい混乱の元となる場合がある。そこで と呼ばれる手法、すなわちinstanceフィールドのみを別のホルダークラスに隔離して、そのホルダークラスがロードされたときにSingletonの初期化がおこわれるよう改善したものが下記である。final class Singleton {これでSingletonクラスがロードされたときではなく、codice_1呼び出しによりSingletonHolderクラスがロードされたときにSingletonクラスが初期化される。上記のSingletonは一般的なJava VM上では機能するが、Android 環境上ではうまく機能しない。これは、Androidの実行環境ではオブジェクトのライフサイクルが一般的なJava VMとは異なるためである。Android環境下ではサスペンドに際してクラス自体がアンロードされることが起こる。クラスがアンロードの後リロードされ、 onCreate()等によってオブジェクトの最初期化が促される。こうした一連の動作によりstaticフィールド上のインスタンスは再生成されてしまう。Android環境下では専用にandroid.app.Applicationクラスが提供されているので、継承して独自クラスを作成しAndroidManifest.xmlに記述を行う。このように、SingletonパターンはJavaという言語だけで考えてはならず、実行環境によってもあり方が変わってくるので注意が必要である。Androidのようにフレームワーク内でSingletonを行いたい場合はフレームワーク提供の機構を使うことを第一に考えなくてはならない。バージョン5.0以降のPHP では、可視性、クラス関数、クラス変数などの機能を備えてより Java に近い仕様となったため、Javaの例と同じ原理で Singleton パターンを実現できる。ソースコードも Java のサンプルコードとほとんど同じものになるため、ここでは省略する。C++ ではクラスのコンストラクタ、コピーコンストラクタとコピー代入演算子を private におくことで唯一となる。class Singleton {private:public:};C++11ではコンパイラが生成する関数へのdefault/delete指定により、コンストラクタ以外はprivateに置かなくてもよくなった。class Singleton {private:public:};扱い次第では、グローバル変数のように機能させることもできる。例えば Java にグローバル変数はないと言われているが、この Singleton パターンで Singleton クラスを作成することで、コード中のどこからでも同一のインスタンスにアクセスすることができる。これはグローバル変数そのものであり、ゆえに Singleton パターンはグローバル変数と同様の問題を引き起こす危険性をはらんでいる。ただし、パッケージ(名前空間)を指定することにより、インスタンスにアクセス可能なコード範囲を制限し、この問題を回避ないしは軽減することはできる。また、コードを工夫すればインスタンスの個数制限を設けることもできる。たとえば、上記のサンプルコード中の getInstance() を複数回呼び出したとき、10回目までは毎回新しいインスタンスを生成するが、11回目以降は以前のインスタンスを再利用する、といったような機構である。これは単なるグローバル変数で実現することはできない利点である。Singletonパターンを拡張したデザインパターンとしてと呼ばれるものがある。これはSingletonで生成されるインスタンスを連想配列で複数保持する。ただしMultiton パターンはユニットテストを難しくし、ガーベジコレクションのある言語ではオブジェクトへの強い参照によりメモリリークを起こす恐れがあることも念頭に置く必要がある。

出典:wikipedia

LINEスタンプ制作に興味がある場合は、
下記よりスタンプファクトリーのホームページをご覧ください。