3. デザインパターン
デザインパターンの多くは、コードのスケーラビリティの問題を解決するためのものであり
、開発の初期段階では、特に必要な場合を除き、過度に設計して複雑なデザインパターンを適用してはなりません。代わりに、コードに問題がある場合は、問題をリファクタリングし、原則とパターンを適用します。これにより、初期段階での過剰設計を効果的に回避できます。
デザインパターンが行うことは分離です。
作成モードは作成コードと使用コードを分離し、
構造モードはさまざまな機能コードを分離し、
動作モードはさまざまな動作コードを分離します。
1.作成
一般的に使用されるのは、シングルトン モード、ファクトリ モード (ファクトリ メソッドと抽象ファクトリ)、ビルダー モードです。
一般的には使用されないものは次のとおりです。 プロトタイプ モード
作成パターンは主にオブジェクト作成の問題を解決し、複雑な作成プロセスをカプセル化し、オブジェクトの作成コードと使用コードを分離します。
-
シングルトン パターンは、グローバルに一意のオブジェクトを作成するために使用されます。
古典的な実装:ハングリー、怠惰、二重チェック、静的内部クラス、列挙型
代替のシングルトン ソリューション:
グローバルな一意性は、ファクトリ パターンと IOC コンテナを通じて保証されます。
-
ファクトリ パターンは、異なるが関連するタイプのオブジェクト (同じ親クラスまたはインターフェイスを継承するサブクラスのグループ) を作成するために使用され、指定されたパラメータによって作成するオブジェクトのタイプが決定されます。オブジェクト作成のロジックが複雑でない場合は、ファクトリ パターンを使用せずに、 new を介して直接
オブジェクトを作成するだけで十分です。作成ロジックが複雑で「大きなプロジェクト」である場合は、ファクトリ パターンを使用してオブジェクト作成プロセスをカプセル化し、オブジェクトの作成と使用を分離することを検討してください。
- ファクトリ モードは非常に古典的なアプリケーション シナリオです。依存関係注入フレームワーク (Spring IOC など) は、特定のビジネス コードから分離された集中的な方法でオブジェクトを作成、アセンブル、管理するために使用され、プログラマーが開発に集中できるようにします。ビジネスコードの。
純正モデルを使用するかどうかの判断基準は以下の通りです。
1. カプセル化の変更: 作成ロジックが変更される可能性があります。ファクトリ クラスにカプセル化された後、作成ロジックの変更は呼び出し元に対して透過的です。
2. コードの再利用: 独立したファクトリ クラスに分離して再利用できるコードを作成します。
3. 複雑さを分離する: 複雑な作成ロジックをカプセル化します。呼び出し元はオブジェクトの作成方法を理解する必要がありません。
4. 複雑さの制御: 作成コードを抽出して、元の関数またはクラスの責任を 1 つにし、コードをより簡潔にします。 - ファクトリ モードは非常に古典的なアプリケーション シナリオです。依存関係注入フレームワーク (Spring IOC など) は、特定のビジネス コードから分離された集中的な方法でオブジェクトを作成、アセンブル、管理するために使用され、プログラマーが開発に集中できるようにします。ビジネスコードの。
-
ビルダー モードは、複雑なオブジェクトを作成するために使用されます。これは、さまざまなオプションのパラメーターを設定することでさまざまなオブジェクトを作成するように「カスタマイズ」できます。
- アプリケーションシナリオ:
1. クラスの必須属性はコンストラクターに配置され、オブジェクトが強制的に作成されるときに設定されます。必須属性が多数ある場合、これらの必須属性がコンストラクターで設定されている場合、コンストラクターには長いパラメーター リストが含まれます。set() メソッドを通じて必須属性を設定すると、これらの必須属性が入力されたかどうかを検証するロジックを配置する場所がなくなります。
2. クラスの属性間に特定の依存関係または制約がある場合、set() メソッドの設計思想でコンストラクターを使用すると、これらの依存関係または制約の検証ロジックを配置する場所がありません。
3. 不変オブジェクトを作成します。オブジェクトの作成後、内部属性値を変更することはできません。この機能を実現するために、クラス内で set() メソッドを公開することはできません。コンストラクターが set() メソッドと連携してプロパティ値を設定する方法は適用されません。 -
プロトタイプ モードでは、作成時間を節約するために既存のオブジェクトを複製することにより、比較的高い作成コストでオブジェクトを作成します。
2.構造タイプ
一般的に使用されるのは、プロキシ モード、ブリッジ モード、デコレータ モード、アダプタ モードです。
あまり一般的には使用されないものは、ファサード モード、コンビネーション モード、フライウェイト モードです。
構造設計パターンは主に「クラスやオブジェクトの組み合わせやアセンブリ」の問題を解決します。
-
プロキシモード: プロキシモードは、元のクラスのインターフェースを変更せずに、元のクラスのプロキシクラスを定義するモードであり、機能拡張ではなくアクセス制御が主な目的であり、これがデコレータモードとの最大の違いです。
- アプリケーションシナリオ:
非機能要件: モニタリング、統計、認証、電流制限、トランザクション、冪等性、ログ、RPC、キャッシュ、その他のアプリケーション シナリオなど。
- アプリケーションシナリオ:
-
ブリッジ モード: ブリッジ モードの目的は、インターフェイス部分を実装部分から分離し、比較的簡単かつ独立して変更できるようにすることです。
インターフェイスは「抽象クラス」や「インターフェイス」を指すのではなく、スケルトン コードのみ実際のビジネス ロジックは、定義内の「実装」に委任して完成させる必要があります。
実装は「インターフェイス実装クラス」ではなく、独立した「クラス ライブラリ」のセットです。
「抽象」と「実装」は独立して開発され、オブジェクト間の構成関係によって組み立てられます。 -
デコレータ モード: デコレータ モードは、元のクラスのインターフェイスを変更せずに元のクラスの機能を強化し、複数のデコレータのネストされた使用をサポートします。
主に継承関係が複雑すぎる問題の解決、継承の組み合わせによる置き換え、元のクラスへの拡張機能の追加などを行っています。
複数のデコレータをプリミティブ クラスにネストできます。デコレータ クラスは、元のクラスと同じ抽象クラスまたはインターフェイスを継承する必要があります。 -
アダプター パターン: アダプター パターンは、後から考えられた修復戦略です。アダプターは元のクラスとは異なるインターフェイスを提供しますが、プロキシ モードとデコレーター モードは元のクラスと同じインターフェイスを提供します。
-
ファサード モード: きめの細かいインターフェイスをカプセル化し、それぞれのきめの細かいインターフェイスを組み合わせた高レベルのインターフェイスを提供することで、インターフェイスの使いやすさを向上させたり、パフォーマンスや分散トランザクションなどの問題を解決したりできます。
-
結合モード: ツリー構造のデータを処理するために使用されます。データはツリー構造で表現できる必要があり、処理ロジックを統合し、各サブツリーを再帰的に処理して、コードの実装を順番に簡素化するために、単一のオブジェクトと結合されたオブジェクトがツリー内のノードと見なされます。
-
フライウェイト モード: フライウェイト オブジェクトが不変オブジェクトであることが前提となります。
3. 行動
一般的に使用されるのは次のとおりです:オブザーバー モード、テンプレート モード、戦略モード、責任の連鎖モード、イテレータ モード
、ステート モード
一般的に使用されないのは、ビジター モード、メモ モード、コマンド モード、インタープリター モード、仲介モードです。
動作設計パターンは主に「クラスまたはオブジェクト間の相互作用」の問題を解決します。
-
オブザーバー パターン: オブザーバーと監視されるコードを分離します。
コード レベルでのデカップリングからアーキテクチャ レベルでのシステム デカップリング、または一部の製品設計アイデアに至るまで、このモデルの影があります。たとえば、電子メール サブスクリプションや RSS フィードは、本質的にオブザーバー モデルです。
-
テンプレート モード: メソッド内でアルゴリズムのスケルトンを定義し、特定のステップをサブクラスに延期します。
2 つの主要な機能: 再利用と拡張。このうち再利用とは、親クラスで提供されているテンプレートメソッドのコードをすべてのサブクラスで再利用できることを意味します。拡張とは、フレームワークがテンプレート モードを通じて機能拡張ポイントを提供し、フレームワーク ユーザーがフレームワークのソース コードを変更せずに拡張ポイントに基づいてフレームワークの機能をカスタマイズできるようにすることを意味します。
- コールバックは、コードの再利用と拡張というテンプレート パターンと同じ目的を果たします。(JdbcTemplate はコールバックを使用します)
コールバックは合成関係に基づいて実装され、テンプレート モードは継承関係に基づいて実装されます。コールバックはテンプレート パターンよりも柔軟です。
- コールバックは、コードの再利用と拡張というテンプレート パターンと同じ目的を果たします。(JdbcTemplate はコールバックを使用します)
-
戦略パターン: デカップリング戦略の定義、作成、および使用。
アプリケーションシナリオ:1. 長い if-else または switch 分岐の判断を避けます。
2. フレームワークの拡張ポイントを提供する
3. 複雑なコードの場合、ストラテジ モードはオープンクローズ原則を満たすこともでき、新しいストラテジを追加する際、コードの変更を最小限に抑えて一元化し、バグが発生するリスクを軽減します。 -
責任連鎖パターン: 複数のプロセッサが同じリクエストを順番に処理します。チェーン内の各プロセッサは、独自の処理責任を負います
。 アプリケーション シナリオ:フィルター機能とインターセプター機能を実装すると、フレームワーク ユーザーはフレームワークのソース コードを変更せずに、新しいフィルター機能とインターセプト機能を追加できます。
-
イテレータ モード: コレクション オブジェクトを走査するために使用されます。主な機能は、コンテナ コードとトラバーサル コードを分離することです。
-
ステート モード: ゲームやワークフロー エンジンなどのシステム開発でよく使用されます。
これは、状態、イベント、アクションの 3 つの部分で構成されます。このうち、イベントは遷移条件とも呼ばれる。イベントは状態の遷移とアクションの実行をトリガーします。ただし、このアクションは必須ではなく、何もせずに状態を転送するだけでも可能です。
-
ビジター モード: 1 つ以上の操作をオブジェクトのセットに適用できるようにします。設計の意図は、操作とオブジェクト自体を分離し、クラスを単一の責任で維持し、オープンとクローズの原則を満たし、コードの複雑さ。
ビジター モードの場合、学習の主な困難はコードの実装にあります。コードの実装がより複雑になる主な理由は、ほとんどのオブジェクト指向プログラミング言語では関数のオーバーロードが静的にバインドされているためです。つまり、クラスのどのオーバーロード関数を呼び出すかは、実行時のパラメーターの実際の型ではなく、コンパイル時に宣言されたパラメーターの型によって決まります。コードの実装は理解しにくいため、このパターンをプロジェクトに適用するとコードの可読性が低下します。
-
メメント モード: スナップショット モードは、カプセル化の原則に違反することなくオブジェクトの内部状態をキャプチャし、この状態をオブジェクトの外部に保存して、後でオブジェクトを以前の状態に復元できるようにします。
アプリケーションシナリオ:主に紛失防止、元に戻す、復元などに使用されます。
-
コマンド モード: 中心となる実装方法は、関数をオブジェクトにカプセル化することです。
アプリケーションシナリオ:非同期、遅延、キュー実行コマンド、取り消し/やり直しコマンド、ストア コマンド、ログ コマンドなどのコマンドの実行を制御するために使用されます。
-
インタープリター モード: 基本的な考え方は、クラスの大規模で包括的な分析を避けるために、文法分析の作業をさまざまなサブカテゴリに分割することです。一般的なアプローチは、文法規則をいくつかの小さな独立した単位に分割し、次に各単位を解析し、最後にそれらを文法規則全体の解析にマージすることです。
-
中間モード: 設計思想は中間層と非常に似ており、中間層を導入することにより、オブジェクトのグループ間の対話関係が多対多 (ネットワーク関係) から 1 対多 (スター関係) に変換されます。 。このようにして、オブジェクト間の対話が最小限に抑えられ、コードの複雑さが軽減され、コードの可読性と保守性が向上します。