この記事は、初めてパターンの概念に出会った、
Singleton
「e」について聞いた、またはなんとなく作ったものの、まだ何も理解できなかった人を対象としています。いらっしゃいませ!JavaRush の学生は、レベル 15 で初めてパターンに遭遇します。そのとき、予期せずキャップがパターンを「修正」し、
Singleton
遅延実装で実装するように要求します。初めてそれについて聞いた学生は、
Singleton
すぐに大量の質問をします。パターンとは何なのか、なぜ必要なのか、どのような種類のパターンなのか、
Singleton
そして最後に、これはどのような遅延実装なのか、ということです。順番に答えていきましょう。
そもそもパターンとは何でしょうか?
より深く理解するには、歴史からこの質問に答えてみる価値があると思います。プログラマーの中には、Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides という有名な 4 人の著者がいて、興味深いアイデアを思いつきました。
彼らは、プログラムを書くときに、ほぼ同じ問題を解決し、構造的に同じタイプのコードを書かなければならないことが多いことに気づきました。そこで、オブジェクト指向プログラミングでよく使われる代表的なパターンをパターンの形で記述することにしました。この本は 1995 年に
「オブジェクト指向設計のテクニック」というタイトルで出版されました。デザインパターン"。この本のタイトルは長すぎることが判明し、単に「
The Book of the Gang of Four 」として知られるようになりました。初版では 23 のパターンが公開され、その後、さらに数十のパターンが発見されました。
それでは、この段落の「パターンとは何ですか?」という質問に答えて、いくつかの言葉で要約しましょう。
パターンは、一般的な問題に対する標準化された解決策です。 |
そして
Singleton
、これはこれらのパターンの 1 つにすぎません。
なぜパターン(デザインパターン)が必要なのか
パターンを知らなくてもプログラミングは可能です。これは、JavaRush の 15 レベルまでに、その存在について何も知らずに何百ものミニプログラムを作成したという事実を認識するだけで検証できます。これは、パターンが一種のツールであり、その存在がマスターとアマチュアを区別することを示唆しています。
パターンは、典型的な問題の 1 つを正しく解決する方法を説明します。その結果、パターンを知ることで時間を節約できます。アルゴリズムを使用して類似することができます。
たとえば、ブラックジャックと数字を使用した独自の並べ替えアルゴリズムを考え出し、それに多くの時間を費やすことも、かなり前にすでに説明されているアルゴリズムを使用して実装することもできます。パターンも同様です。さらに、パターンを使用すると、コードがより標準化され、適切なパターンを使用すると、このパターンでは間違いがすでに予測されて排除されているため、間違いを犯す可能性が低くなります。それに加えて、パターンについての知識があれば、プログラマーはお互いをよりよく理解できるようになります。同僚のプログラマに何をしてもらいたいかを説明する必要はなく、テンプレートの名前を言うだけで十分です。
要約すると、デザイン パターンは次のことに役立ちます。
- 車輪の再発明ではなく、標準的なソリューションを使用します。
- コードを標準化する。
- 用語を標準化する。
|
このセクションの結論として、さまざまなパターン全体が 3 つの大きなグループに単純化できることに注意してください。
最後にシングルトンパターン
Singleton
生成パターンを指します。直訳すると「孤独」です。このパターンでは、クラスにオブジェクトが 1 つだけ (クラスの 1 つのインスタンス) 存在し、そのオブジェクトにグローバル アクセス ポイントが提供されることが保証されます。このパターンは次の 2 つの場合に使用する必要があることが説明から明らかです。
- プログラム内でどのクラスのオブジェクトも 1 つだけ作成する必要がある場合。たとえば、コンピューター ゲームには「Character」クラスがあり、このクラスにはキャラクター自身を記述するオブジェクトが 1 つだけ含まれている必要があります。
- クラス オブジェクトにグローバル アクセス ポイントを提供する必要がある場合。つまり、プログラム内のどこからでもオブジェクトが呼び出されることを確認する必要があります。そして、悲しいことに、グローバル変数を作成するだけでは十分ではありません。グローバル変数は書き込み保護されておらず、誰でもこの変数の値を変更でき、オブジェクトへのグローバル アクセス ポイントが失われるためです。これらのプロパティは
Singleton
、たとえば、データベースと連携するクラスのオブジェクトがあり、プログラムのさまざまな部分からデータベースにアクセスできるようにする必要がある場合に必要です。また、Singleton
以前に作成されたクラスのインスタンスを他のコードが置き換えていないことも保証されます。
Singleton
これら 2 つの問題は、プログラム内にオブジェクトが 1 つだけ存在する必要があり、そのオブジェクトへのグローバル アクセスが必要であることによって解決されます。レベル 15 の例では、キャップは次のタスクにこのパターンを実装するように要求します (その説明はここにあります)。
条件を注意深く読むと、
Singleton
ここで正確に (Single) が必要な理由が明らかになります。結局のところ、プログラムは各クラスのオブジェクトを 1 つ作成するように求めます:
Sun
、
Moon
、
Earth
。そして、プログラム内の各クラスが作成する太陽、月、地球は 1 つだけであると想定するのが論理的です。そうしないと、もちろん、独自のバージョンのスター ウォーズを作成する場合を除き、不合理になります。
3 つのステップによるJava実装のSingleton
機能 Java のシングルトン動作は、コンストラクターが常に新しいオブジェクトを返すため、通常のコンストラクターを使用して実装することはできません。したがって、
Singleton
'a のすべての実装は、コンストラクターを非表示にし、単一のオブジェクトの存在を制御し、新しく出現するすべてのオブジェクトを「破棄」するパブリック静的メソッドを作成することになります。'a が呼び出された場合
Singleton
、新しいオブジェクトを作成するか (まだプログラム内にない場合)、すでに作成されているオブジェクトを返す必要があります。これを行うには:
#1. – 単一のオブジェクトを含むクラスにプライベート静的フィールドを追加する必要があります。
public class LazyInitializedSingleton {
private static LazyInitializedSingleton instance;
}
#2. – クラス コンストラクター (デフォルト コンストラクター) をプライベートにします (クラス コンストラクターへのアクセスがクラス外で閉じられるため、新しいオブジェクトを返すことができなくなります)。
public class LazyInitializedSingleton {
private static LazyInitializedSingleton instance;
private LazyInitializedSingleton(){}
}
#3。– シングルトンを取得するために使用される静的作成メソッドを宣言します。
public class LazyInitializedSingleton {
private static LazyInitializedSingleton instance;
private LazyInitializedSingleton(){}
public static LazyInitializedSingleton getInstance(){
if(instance == null){
instance = new LazyInitializedSingleton();
}
return instance;
}
}
上記の例は、単にコンストラクターを非表示にして、標準のコンストラクターの代わりに独自のメソッドを提供しているだけなので、やや不格好です。この記事は、JavaRush の学生がこのパターン (および一般的なパターン) に初めて触れられるようにすることを目的としているため、より複雑なシングルトンの実装機能についてはここでは説明しません。プログラムの複雑さに応じて、このパターンのより詳細な改良が必要になる可能性があることにのみ注意してください。たとえば、マルチスレッド環境 (「スレッド」トピックを参照) では、複数の異なるスレッドがシングルトンのゲッター メソッドを同時に呼び出すことができ、個々のスレッドがクラスの複数のインスタンスを作成できるため、上記のコードは動作しなくなります。すぐに。したがって、正しいスレッドセーフ シングルトンを作成するには、まだいくつかの異なるアプローチがあります。しかし、それはまた別の話です =)
そして最後に。キャップが要求した遅延初期化とは何ですか ? 遅延初期化は、遅延初期化とも呼ばれます。これは、リソースを大量に消費する操作 (オブジェクトの作成はリソースを大量に消費する操作) を、事前ではなくオンデマンドで実行するプログラミング手法です。これは基本的にコード
Singleton
「a」で起こっていることです。言い換えれば、オブジェクトは事前にではなく、アクセスされた瞬間に作成されます。遅延初期化の概念が何らかの形で 'om.' と厳密に関連していると想定すべきではありません
Singleton
。遅延初期化は、プロキシやファクトリー メソッドなど、他のジェネレーティブ デザイン パターンでも使用されますが、それはまた別の話です =)
記事の準備には次のソースが使用されました。
- Java シングルトン設計パターンのベスト プラクティスと例
- デザインパターン
- Java の正しいシングルトン
GO TO FULL VERSION