23種類の設計モード(単例モード)について簡単に説明します.
23種類の設計モード(java版)について
単一モード設計モードとは 設計モード(Design Pattern)は、繰り返し使用され、多くの人が知っている、分類された、コード設計経験の総括であり、設計モードを使用する目的は、コードの再利用性を高め、コードが人間の理解思考に合致するようにすることである.
単例モードとは 単一の例は、その名の通り、システム全体に1つのクラスのインスタンスオブジェクトしかありません.
これは何のメリットがありますか? には、スレッドプール、キャッシュ、ダイアログボックス、ログ・オブジェクトなど、1つのインスタンスしか必要としないオブジェクトがあります.複数のインスタンスを作成すると、プログラムの実行異常、実行結果の不一致などの多くの問題が発生します.
単純ではない単例モード 単例モードは分かりやすいように聞こえますが、本当に単例モードを実現するのもそんなに容易ではありません.どのように1つのオブジェクトが1回しかインスタンス化できないことを保証するか、どのようにマルチスレッドの下のスレッドの安全問題を保証するかなどです.
次に、単一のモードを実現するために一歩一歩進みましょう. オブジェクトを作成する方法
new Singleton();
他のオブジェクトがSingletonを作成したい場合はどうなりますか?再作成できますか?
はい、もちろんです.
クラスがあれば、何度もインスタンス化できますか?
答えは:もちろんいいです.あなたのクラスが公開されている限り.
類を公開しないとどうなりますか?
クラスを公開しなければ、同じパッケージ内のクラスだけがインスタンス化でき、何度もインスタンス化できる(若者はけちだ)
外部でインスタンス化できませんか?
もちろんいいです.コンストラクタをプライベートとして定義すると、内部クラスが初期化できるほか、他のオブジェクトも初期化できません.もちろん、インスタンス化できません(生きられません) プライベートコンストラクタは少し不合理だと思いますか?
そうですね.確かに少し不合理です.
どう思う?
クラスの内部に静的メソッドを作成して呼び出すとどうなりますか. なぜ
面白いですが、上の組み合わせを合わせたらどうなりますか? インスタンス化の問題を解決しましたか?
はい、オブジェクトをインスタンス化できますが、インスタンス化されたオブジェクトだけで、オブジェクトが一意であることは保証されていません.
オブジェクトの一意性を保証する方法
上のコードを改造してみましょう マルチスレッドの場合、問題が発生しました.
怠け者モードでは、複数のスレッドが複数のインスタンスを作成する可能性があることを発見しました.これは、単一の例の原則に反しています.
マルチスレッドでのセキュリティ問題をどのように解決しますか? に影響することは明らかである.マルチスレッドをどのように改善しますか?
二重ロックを使用して、まずインスタンスが作成されているかどうかを確認します.作成されていない場合は同期され、最初の同期のみが実行されます. まとめ
ここを見て、単例もそんなに簡単に作成できないのではないかと思って、どのように唯一のインスタンスを保証するか、マルチスレッドの下でどのようにインスタンスを保証するか、どのようにマルチスレッドを最適化するかなどを考える必要がありますが、私たちが一歩一歩勉強すれば、焦らないで、真剣に考えて、もっと練習して、どんなに難しい設計モードでも学ぶことができます.その後、工場モデルに参加して、単例の作成を最適化し続けます.
単一モード
new Singleton();
はい、もちろんです.
答えは:もちろんいいです.あなたのクラスが公開されている限り.
クラスを公開しなければ、同じパッケージ内のクラスだけがインスタンス化でき、何度もインスタンス化できる(若者はけちだ)
もちろんいいです.コンストラクタをプライベートとして定義すると、内部クラスが初期化できるほか、他のオブジェクトも初期化できません.もちろん、インスタンス化できません(生きられません)
public Singleton{
private Singleton(){ }
}
そうですね.確かに少し不合理です.
Singleton
種類のインスタンスが必要だからです.このクラスのコンストラクタを呼び出すことができますが、インスタンス化できるクラスはありません.そのインスタンスは得られません.これは「鶏が卵を産んで、卵が鶏を産んで」のように、クラスの内部でコンストラクタを呼び出すしかありません.クラスの内部に静的メソッドを作成して呼び出すとどうなりますか.
public Singleton{
private Singleton(){ }
public static Singleton getInstance(){
}
}
getInstance()
を呼び出してオブジェクト名ではなくクラス名を使用するのですか?getInstance()
メソッドは静的であり、静的メソッドはオブジェクトではなくクラスに属するため、呼び出すにはクラス名しか使用できません.getInstance()
メソッドでインスタンスの作成を快適に行うことができます.public Singleton{
private Singleton(){ }
public static Singleton getInstance(){
return new Singleton();
}
}
はい、オブジェクトをインスタンス化できますが、インスタンス化されたオブジェクトだけで、オブジェクトが一意であることは保証されていません.
上のコードを改造してみましょう
//
public Singleton{
//
private static Singleton singleton = null;
private Singleton(){ }
public static Singleton getInstance(){
if(singleton == null){
return new Singleton();
}
else{
return singleton;
}
}
}
//
public Singleton{
// ( )
private static Singleton singleton = new Singleton()l;
private Singleton(){ }
public static Singleton getInstance(){
return singleton;
}
}
以上の2つのモードは、単一のオブジェクトを作成します.怠け者モードでは、複数のスレッドが複数のインスタンスを作成する可能性があることを発見しました.これは、単一の例の原則に反しています.
synchronized
キー同期コードブロックの使用 //
public Singleton{
//
private static Singleton singleton = null;
private Singleton(){ }
//
public static synchronized Singleton getInstance(){
if(singleton == null){
return new Singleton();
}
else{
return singleton;
}
}
}
しかし、同期は最初の実行のみであり、上記の実行のたびに同期が効率二重ロックを使用して、まずインスタンスが作成されているかどうかを確認します.作成されていない場合は同期され、最初の同期のみが実行されます.
//
public Singleton{
// volatile Single ,
private volatile static Singleton singleton = null;
private Singleton(){ }
//
public static Singleton getInstance(){
if(singleton == null){
synchronized (Singleton.class){
if(singleton == null){
singleton = new Singleton();
}
}
}
return singleton;
}
}
ここを見て、単例もそんなに簡単に作成できないのではないかと思って、どのように唯一のインスタンスを保証するか、マルチスレッドの下でどのようにインスタンスを保証するか、どのようにマルチスレッドを最適化するかなどを考える必要がありますが、私たちが一歩一歩勉強すれば、焦らないで、真剣に考えて、もっと練習して、どんなに難しい設計モードでも学ぶことができます.その後、工場モデルに参加して、単例の作成を最適化し続けます.