シングルトン パターン
動機
場合によっては、クラスのインスタンスを 1 つだけ持つことが重要です。たとえば、システムにはウィンドウ管理のインスタンスが 1 つだけ必要です。
シングルトン パターンは最も単純な設計パターンです。クラスはそれ自体をインスタンス化し、インスタンスが 1 つだけであることを保証し、このインスタンスにアクセスするための入り口を提供する責任があります。
目的
1. インスタンスが 1 つだけ作成されるようにします。
2. このインスタンスへのアクセスを提供します。
final を使用して一度作成されることを確認し、プライベート コンストラクターを使用してインスタンス化されないようにします。パブリック getInstance メソッドにより、外部アクセスが保証されます。以下はハングリー モードです:
public class Singleton { private static final Singleton instance = new Singleton(); private Singleton() {} public static Singleton getInstance() { return instance; } }
レイジー モード:
public class SingletonDemo { private static volatile SingletonDemo instance = null; private SingletonDemo() { } public static SingletonDemo getInstance() { if (instance == null) { synchronized (SingletonDemo .class){ if (instance == null) { instance = new SingletonDemo (); } } } return instance; } }
適用可能なシナリオと例
1. ログが作成されるたびに Logger インスタンスが作成されるのを防ぎます。印刷された。
2. コントロール クラス。通常、システム全体にコントロール インスタンスは 1 つだけあります。
具体的な問題と実装
1. スレッド セーフ、堅牢なシングルトン パターンはスレッド セーフである必要があります。
2. Lazy モードは二重ロック機構を使用します。
3. ハングリー モードでは、プログラムのロード時にインスタンス化される静的変数が使用され、インスタンスが 1 つだけ存在することが保証されます。
4. 抽象ファクトリとファクトリ メソッドは通常、ファクトリが 1 つだけになるようにシングルトン モードで設計されます。
5. シリアル化と逆シリアル化を使用する場合、readResolve 関数を使用してこの状況を回避しますが、シリアル化を使用しないことをお勧めします。
public class Singleton implements Serializable { ... // This method is called immediately after an object of this class is deserialized. // This method returns the singleton instance. protected Object readResolve() { return getInstance(); } }
重要なポイント
1. マルチスレッドプログラムでは、データの同期に注意してください。
2. 複数のオブジェクトが作成されるのを避けるために、シリアル化するときに readResolve メソッドを使用してインスタンスを返します。
3. 複数のクラスローダーによってロードされる場合、複数のインスタンスが作成されます。
シンプル ファクトリ パターン
動機
シンプル ファクトリ パターンは、抽象ファクトリとファクトリ メソッドの基礎および予備実装です。
目的
1. オブジェクトのインスタンス化の詳細をクライアントに公開しないでください。
2. 共通のインターフェースを通じてオブジェクトを作成します。
実装
実装は非常に簡単です:
1. クライアントが製品を必要とするとき、それを作成するために new を使用しませんが、製品の説明をファクトリに提供し、ファクトリが新しい製品を提供できるようにします。
2. ファクトリはクライアントに対して製品をインスタンス化します。
3. クライアントは抽象的な製品を使用し、製品の特定の実装には関心がありません。
例
1. 図形を描画するための描画プログラム。形状は製品インターフェイス、三角形は具体的な製品です。工場を作成し、顧客の説明に従って対応する製品を作成します。ただし、新しいシェイプを追加する場合は、ファクトリ クラスを変更する必要があります。
具体的な問題と実装
1. 新しい製品を追加する場合、工場を変更する必要があります。
public class ProductFactory{ public Product createProduct(String ProductID){ if (id==ID1) return new OneProduct(); if (id==ID2) return new AnotherProduct(); ... // so on for the other Ids return null; //if the id doesn't have any of the expected values } ... }
通常、商品の説明は if ステートメントで判断し、別の商品をインスタンス化します。新しい商品がある場合は、新しい判断を追加する必要があります。この問題は、抽象ファクトリー パターンを通じて解決できます。
概要
1. ファクトリ パターンは、本当に必要な場合にのみ使用してください。そうでない場合は、プログラムの複雑さが増すだけです。たとえば、複数のオブジェクトが同様の基本タイプを持つ場合は、単純なファクトリ パターンを使用してオブジェクトを作成することを検討できます。均一に。
2. シンプル ファクトリには判断分岐ステートメントが多く、変更を閉じるオープンクローズの原則に違反します。そのため、一部の固定された単純なプログラムにはシンプル ファクトリ モードを使用し、一部のプログラムにはシンプル ファクトリ モードを使用するのが賢明です。頻繁な拡張を必要とする一部の複雑なプログラムでは、抽象ファクトリ パターンまたはファクトリ メソッド パターンが使用されます。
Java デザイン パターン プログラミングにおけるシングルトン パターンとシンプルなファクトリー パターンに関するその他の記事については、PHP 中国語 Web サイトに注目してください。