デザインパターンのJava – 実例チュートリアル
イントロダクション
デザインパターンはソフトウェア開発者の間で非常に人気があります。デザインパターンとは、共通のソフトウェア問題に対する明確な解決策です。
デザインパターンの利点の一部は次のとおりです:
-
- デザインパターンはすでに定義されており、再発する問題を解決するための産業標準的なアプローチを提供しているため、デザインパターンを適切に使用することで時間を節約できます。私たちのJavaベースのプロジェクトで使用できる多くのJavaデザインパターンがあります。
-
- デザインパターンの使用は再利用性を促進し、より堅牢で保守性の高いコードを実現します。これによりソフトウェア製品の所有コスト(TCO)を削減するのに役立ちます。
- デザインパターンがすでに定義されているため、コードを理解しやすく、デバッグも容易です。これにより開発が迅速化し、新しいチームメンバーも簡単に理解できます。
Javaのデザインパターンは、生成、構造、および振る舞いのデザインパターンの3つのカテゴリに分けられます。
この記事は、すべてのJavaデザインパターンの記事の一覧としての役割を果たしています。
創造的なデザインパターン
創造的なデザインパターンは、特定の状況に最適な方法でオブジェクトをインスタンス化するための解決策を提供します。
1. シングルトンパターン
シングルトンパターンは、クラスのインスタンス化を制限し、Java仮想マシン内にクラスの唯一のインスタンスが存在することを確実にするものです。シングルトンパターンの実装は、常に開発者の間で議論の的となってきました。
Note
2. ファクトリーパターン (The factory pattern)
ファクトリーデザインパターンは、スーパークラスに複数のサブクラスがあり、入力に基づいてそのサブクラスの1つを返す必要がある場合に使用されます。このパターンは、クライアントプログラムからクラスのインスタンス化の責任をファクトリークラスに移します。ファクトリークラスにはシングルトンパターンを適用するか、ファクトリーメソッドを静的にすることができます。
Note
3. 抽象ファクトリーパターン
抽象ファクトリーパターンは、ファクトリーパターンと似ており、ファクトリーの集合体です。Javaでファクトリーデザインパターンに詳しい方は、異なるサブクラスを返す単一のファクトリークラスが存在し、そのクラスはif-else文やswitch文を使用しています。抽象ファクトリーパターンでは、if-elseブロックを排除し、各サブクラスごとにファクトリークラスを持ち、それぞれのファクトリークラスに基づいてサブクラスを返す抽象ファクトリークラスを用意します。
Note
4. ビルダーパターン
ビルダーパターンは、オブジェクトが多くの属性を持つ場合に、ファクトリーと抽象ファクトリーデザインパターンの問題を解決するために導入されました。このパターンは、大量のオプションパラメーターと一貫性のない状態の問題を、オブジェクトを段階的に組み立てて最終オブジェクトを返すメソッドを提供することで解決します。
Note
5. プロトタイプパターン (Purototaipu pattān)
プロトタイプパターンは、オブジェクトの作成にコストと時間とリソースがかかる場合や、既に類似のオブジェクトが存在する場合に使用されます。したがって、このパターンは元のオブジェクトを新しいオブジェクトにコピーし、必要に応じて修正するメカニズムを提供します。このパターンでは、Javaのクローンを使用してオブジェクトをコピーします。プロトタイプデザインパターンでは、コピーするオブジェクトはコピー機能を提供する必要があります。他のクラスが行うべきではありません。ただし、オブジェクトのプロパティの浅いコピーまたは深いコピーを使用するかどうかは、要件と設計の決定に依存します。
Note
構造的なデザインパターン
構造的なデザインパターンは、クラスの構造を作成するための異なる方法を提供します(例えば、継承と組成を使用して小さなオブジェクトから大きなオブジェクトを作成する)。
アダプターパターン
アダプターデザインパターンは構造デザインパターンの一つであり、関連性のない2つのインターフェースを一緒に動作させるために使用されます。これらの関連性のないインターフェースを結び付けるオブジェクトはアダプターと呼ばれます。
Note
2. コンポジットパターン
私たちは部分と全体の階層を表現する必要がある場合に、コンポジットパターンを使用します。構造を作成する必要があり、構造内のオブジェクトを同じように扱う必要がある場合、コンポジットデザインパターンを適用することができます。
Note
3. プロキシーパターン
プロキシーパターンは、別のオブジェクトにアクセスを制御するためのプレースホルダーを提供します。このパターンは、機能への制御されたアクセスを提供する場合に使用されます。
Note
4. フライウェイトパターン
フライウェイトデザインパターンは、同じクラスの多くのオブジェクトを作成する必要がある場合に使用されます。すべてのオブジェクトがメモリスペースを消費するため、低メモリデバイス(モバイルデバイスや組み込みシステムなど)では重要です。フライウェイトデザインパターンは、オブジェクトを共有することによってメモリの負荷を軽減するために適用することができます。
JavaにおけるStringプールの実装は、フライウェイトパターンの実装の最も優れた例の一つです。
Note
5. ファサードパターン (Fasadopatān)
ファサードパターンは、クライアントアプリケーションがシステムと簡単にやり取りするのをサポートするために使用されます。
Note
6. ブリッジパターン
インターフェースと実装の両方にインターフェース階層がある場合、ブリッジデザインパターンは、インターフェースと実装の間の結びつきを弱め、クライアントプログラムから実装の詳細を隠すために使用されます。ブリッジデザインパターンの実装では、継承よりもコンポジションを優先する考え方が採用されています。
Note
7. デコレーターパターン
デコレーターデザインパターンは、オブジェクトの機能をランタイムで変更するために使用されます。同時に、同じクラスの他のインスタンスには影響を与えないため、個々のオブジェクトには変更された動作が与えられます。デコレーターデザインパターンは、アダプターパターン、ブリッジパターン、またはコンポジットパターンのような構造的なデザインパターンの一つであり、抽象クラスまたはインターフェースと組成を使用して実装されます。オブジェクトの振る舞いを拡張するために継承や組成を使用しますが、これはコンパイル時に行われ、クラスのすべてのインスタンスに適用されます。ランタイムで新しい機能を追加することや既存の動作を削除することはできませんが、ここでデコレーターパターンが役立ちます。
Note
行動設計パターン
行動パターンは、オブジェクト間のより良い相互作用と、緩い結合と柔軟性を提供して容易に拡張するための解決策を提供します。
1. テンプレートメソッドパターン
テンプレートメソッドパターンは、行動デザインパターンであり、メソッドスタブの作成や実装の一部をサブクラスに委任するために使用されます。テンプレートメソッドは、アルゴリズムの実行手順を定義し、すべてまたは一部のサブクラスで共通のデフォルト実装を提供することができます。
Note
2. 仲介者パターン
中央集権的な通信手段を提供するために、仲介者デザインパターンはシステム内の異なるオブジェクト間の間を仲介します。オブジェクトが直接的に相互作用すると、システムの構成要素が互いに密結合され、保守性が低下し、柔軟な拡張が難しくなります。仲介者パターンは、オブジェクト間の通信のための仲介者を提供し、オブジェクト間の疎結合を実現することに注力しています。仲介者はオブジェクト間のルーターとして機能し、通信手段を提供するための独自のロジックを持つことができます。
Note
3. 責任連鎖パターン
チェーン オブ レスポンシビリティ パターンは、クライアントからのリクエストをオブジェクトのチェーンに渡して処理するために使用され、ソフトウェアの設計で緩やかな結合を実現します。そして、チェーン内のオブジェクトがリクエストの処理を担当する人を決定し、リクエストを次のオブジェクトに送る必要があるかどうかを判断します。
日本語での一つのオプション:
私たちは、try-catchブロックのコード内で複数のcatchブロックを持つことができるということを知っています。ここでは、それぞれのcatchブロックは特定の例外を処理するためのプロセッサのようなものです。したがって、tryブロックで例外が発生すると、最初のcatchブロックに送られて処理されます。もしcatchブロックが処理できない場合、要求はチェーン内の次のオブジェクト(つまり、次のcatchブロック)に転送されます。最後のcatchブロックですら処理できない場合、例外はチェーンの外部にある呼び出しプログラムに投げられます。
Note
4. オブザーバーパターン
オブザーバーデザインパターンは、あるオブジェクトの状態に興味があり、その状態が変化するたびに通知を受けたい場合に役立ちます。オブザーバーパターンでは、他のオブジェクトの状態を監視するオブジェクトをオブザーバーと呼び、監視されるオブジェクトをサブジェクトと呼びます。
Javaは、java.util.Observableクラスとjava.util.Observerインターフェースを介して、観察者パターンを実装するための組み込みプラットフォームを提供します。しかし、実装が制限されているため広く使われておらず、Javaではクラスに複数の継承を提供していないため、観察者パターンを実装するためだけにクラスを拡張することになりがちです。Java Message Service(JMS)は、メディエータパターンと観察者パターンを併用して、アプリケーションが他のアプリケーションにデータを購読および公開することを可能にします。
Note
5. ストラテジーパターン
ストラテジーパターンは、特定のタスクに対して複数のアルゴリズムが存在し、クライアントが実行時に使用する具体的な実装を決定する必要がある場合に使用されます。ストラテジーパターンはポリシーパターンとも呼ばれています。複数のアルゴリズムを定義し、クライアントアプリケーションが使用するアルゴリズムをパラメータとして渡すことで実現します。
このパターンの最も良い例の一つは、Comparatorパラメーターを受け取るCollections.sort()メソッドです。異なるComparatorインターフェースの実装に基づいて、オブジェクトは異なる方法でソートされます。
Note
6. コマンドパターン
コマンドパターンは、要求とレスポンスのモデルにおいて緩い結合を実現するために使用されます。このパターンでは、要求はインボーカーに送信され、インボーカーはそれをカプセル化されたコマンドオブジェクトに渡します。コマンドオブジェクトは、要求をレシーバーの適切なメソッドに渡して特定のアクションを実行します。
Note
7. ステートパターン
こちらは一つのオプションです。
オブジェクトが内部の状態に基づいて振る舞いを変える必要がある場合、状態デザインパターンを使用します。オブジェクトの状態に基づいて振る舞いを変更する必要がある場合、オブジェクトに状態変数を持たせ、その状態に基づいて異なるアクションを実行するために if-else 条件ブロックを使用することができます。このような状況を扱うために、状態パターンはコンテキストと状態の実装を介して、システム的かつ疎結合な方法を提供するために使用されます。
Note
8.ビジターパターン
訪問者パターンは、同様の種類のオブジェクトのグループに対して操作を行わなければならない場合に使用されます。訪問者パターンのおかげで、オブジェクトから操作ロジックを別のクラスに移動することができます。
Note
9. インタープリターパターン
インタプリターパターンは、言語の文法的表現を定義し、その文法に対応するインタプリターを提供するために使用されます。
10. イテレーターパターン
イテレーターパターンは、行動パターンの一つであり、オブジェクトのグループをトラバースするための標準的な方法を提供するために使用されます。イテレーターパターンは、Java Collection Frameworkで広く使用されており、イテレーターインターフェースはコレクションのトラバースに必要なメソッドを提供します。このパターンは、要件に基づいて異なる種類のイテレーターを提供するためにも使用されます。イテレーターパターンは、コレクションをトラバースする実際の実装を隠し、クライアントプログラムはイテレーターメソッドを使用します。
Note
11. メメントパターン
「 memento(メメント)デザインパターンは、後で状態を復元できるようにオブジェクトの状態を保存したい場合に使用されます。このパターンは、オブジェクトの保存された状態データがオブジェクトの外部からアクセスできないように実装され、保存された状態データの整合性を保護します。」
メメントーパターンは、オリジネーターとケアテイカーの2つのオブジェクトで実装されます。オリジネーターは、保存および復元する必要のあるオブジェクトの状態を指します。オリジネーターは内部クラスを使用してオブジェクトの状態を保存します。この内部クラスは「メメント」と呼ばれ、他のオブジェクトからアクセスできないようにプライベート設定されています。
さまざまなデザインパターン
ギャングオブフォーのデザインパターンに含まれないデザインパターンはたくさんあります。いくつかの人気のあるデザインパターンを見てみましょう。
1. DAOデザインパターン
データアクセスオブジェクト(DAO)デザインパターンは、データ永続性のロジックを別の層に切り離すために使用されます。データベースとの連携するシステムを設計する際に非常に人気のあるパターンです。サービス層とデータアクセス層を分けることで、アプリケーション内でのロジックの分離を実現します。
Note
2. 依存性注入パターン
依存性注入パターンにより、私たちはハードコードされた依存関係を排除し、アプリケーションを疎結合で、拡張可能で、メンテナンスしやすくすることができます。Javaでは依存性注入を実装して、依存性の解決をコンパイル時から実行時に移動させることができます。Springフレームワークは依存性注入の原則に基づいて構築されています。
Note
3. MVCパターン (MVC pataan)
モデル・ビュー・コントローラー(MVC)パターンは、ウェブアプリケーションを作成するための最も古いアーキテクチャパターンの一つです。
結論:
この記事は、Javaデザインパターンを簡潔にまとめています。 (Kono kiji wa, Java dezain pāton o kantankaku ni matometeimasu.)
私たちのGitHubリポジトリから、Javaデザインパターンの例コードをチェックすることができます。
もっとJavaのチュートリアルで学びを続けてください。