デザイン パターンが従う 7 つのデザイン原則

デザインパターンとは?

1. デザインパターンの定義

デザインパターンは、ソフトウェア設計で繰り返されるさまざまな問題の解決策であり、コードの記述を完了するために直接使用されるのではなく、さまざまな状況で問題を解決する方法を記述するために使用されます。 . 設計パターンは、コードの再利用性、スケーラビリティ、保守性、柔軟性などを向上させるのに役立ちます。設計パターンを使用する最終的な目標は、コードの高い凝集度と低い結合を実現することです。

2. デザインパターンの分類

23 の設計パターンがあり、大まかに創造的、動作的、構造的の3 つのカテゴリに分類できます。

(1)、作成モード:

オブジェクトのインスタンス化のモードである作成モードは、オブジェクトのインスタンス化プロセスを分離するために使用されます。

  1. シングルトン モード: 特定のクラス インテリジェンスにはインスタンスがあり、グローバル アクセス ポイントを提供します。
  2. ファクトリ モード: ファクトリ クラスは、渡されたパラメータに基づいて、作成する製品クラスのインスタンスを決定します。
  3. 抽象ファクトリ パターン: 具体的なクラスを明示的に指定せずに、関連オブジェクトまたは依存オブジェクトのファミリを作成します。
  4. ビルダー モード: 複雑なオブジェクトの作成プロセスをカプセル化し、段階的に構築できます。
  5. プロトタイプ パターン: 既存のインスタンスをコピーして新しいインスタンスを作成します。

(2)、構造モード:

クラスまたはオブジェクトをグループ化して、より大きな構造を形成します。

  1. デコレーター パターン: オブジェクトに新しい機能を動的に追加します。
  2. プロキシ モード: このオブジェクトへのアクセスを制御するために、他のオブジェクトにプロキシを提供します。
  3. ブリッジ パターン: 抽象化を実装から分離して、両方が独立して変化できるようにします。
  4. アダプター パターン: クラスのメソッド インターフェイスを、クライアントが必要とする別のインターフェイスに変換します。
  5. 複合モード: オブジェクトをツリー構造に構成して、「部分 - 全体」階層を表します。
  6. 外観モード: サブシステム内のインターフェイスのグループにアクセスするための統一された方法を提供します。
  7. Flyweight モード: 共有テクノロジにより、多数のきめ細かいオブジェクトを効果的にサポートします。

(3)、行動モデル

責任とアルゴリズムの分割により、クラスとオブジェクトがどのように相互作用するか。

  1. 戦略パターン: 一連のアルゴリズムを定義し、それらをカプセル化し、それらを交換可能にします。
  2. テンプレート パターン: サブクラスの実装にいくつかの手順を延期しながら、アルゴリズム構造を定義します。
  3. コマンド モード: コマンド リクエストをオブジェクトとしてカプセル化して、さまざまなリクエストをパラメータ化に使用できるようにします。
  4. 反復子モード: オブジェクトの内部構造を公開せずに、集約オブジェクト内の各要素をトラバースしてアクセスする方法。
  5. オブザーバー パターン: オブジェクト間の 1 対多の依存関係。
  6. アービター パターン: 中間オブジェクトを使用して、一連のオブジェクトの相互作用をカプセル化します。
  7. Memento パターン: カプセル化を壊さずにオブジェクトの内部状態を維持します。
  8. インタープリター モード: 言語を指定して、その文法の表現を定義し、インタープリターを定義します。
  9. 状態パターン: 内部状態が変化したときにオブジェクトの動作を変更できるようにします。
  10. Chain of Responsibility モード: 複数のオブジェクトがリクエストを処理できるように、リクエストの送信者と受信者を切り離します。
  11. 訪問者パターン: データ構造を変更せずに、一連のオブジェクト要素に新しい機能を追加します。

元のリンク

3. デザインパターンの7原則

1. オープン クローズド プリンシパル (OCP)

開閉原理 (Open-ClosedPrincinple、OCP と呼ばれる):

モジュール、クラス、または関数は、変更のために閉じ、拡張のために開く必要があります。ソース コードを変更せずに拡張します。

  • 元のコードを変更すると、元の正常な機能に問題が発生する可能性があります。
  • 要件が変更された場合は、新しいメソッドまたはプロパティを追加して拡張することで実現できます。

開閉の原則は、最も基本的な設計原則であり、オブジェクト指向設計の核心です。この原則に従うことで、オブジェクト指向テクノロジが主張する大きなメリット、つまり保守性、スケーラビリティ、再利用性、優れた柔軟性を実現できます。その他の設計原則は、開閉原理の具体的な形であり、オブジェクト指向で説明すると、開閉原理が最上位の抽象クラスであり、残りの 5 つのクラスがその具象化です。


2. 単一責任の原則 (SRP)

単一責任の原則 (SRP):

クラスに関する限り、クラスが変更される理由は 1 つだけであるべきです。各クラスは1 つの原則を実装する必要があります。それ以外の場合は、クラスを分割する必要があります。

クラスがあまりにも多くの責任を負う場合, それはこれらの責任を結合することと同じです. 1 つの責任の変更は, このクラスが他の責任を完了する能力を弱めたり阻害したりする可能性があります. この結合は壊れやすい設計につながる可能性があります. 変更が発生すると,意匠に思わぬダメージを与えます。

ソフトウェア設計とは、責任を発見し、それらの責任を互いに分離することです。

簡単に言えば、クラスの機能は、食料品店のようにすべてを網羅するのではなく、単一であるべきです。


3. 依存関係逆転 (inversion) 原則 (DIP)

依存性逆転の原則 (依存性逆転の原則、略して DIP):

オープンとクローズの原則の基礎であり、具体的な内容は、具体性よりも抽象性に依存するインターフェイス プログラミングです。

1. 高レベル モジュールは低レベル モジュールに依存してはならず、どちらも抽象化に依存する必要があります。

2. 抽象化は詳細に依存すべきではなく、詳細は抽象化に依存すべき (ASD)

最初の文は次のように理解できます。たとえば、ユーザー ログインおよび登録モジュールの具体的な実装プロセスは、フロント エンドがフォームをバック エンドに送信し、バック エンドがデータに従ってデータベースを読み書きすることです。フォーム。Java を使用してデータベースにアクセスするプロセスでは、JDBC を使用し、最初にデータベース アクセスをカプセル化する関数 (下の関数) を記述し、次にこの関数を特定のビジネス ロジック (高レベル関数) で呼び出します。 -レベル モジュールの依存関係 低レベル モジュールこの方法では、上位モジュールが下位モジュールにバインドされているため、上位モジュールの再利用が不可能になります.コンピュータのマザーボードがこの原則を採用している場合、マザーボードが損傷した場合、CPU、メモリ、グラフィックス カードなどは全て交換しなければならないので、この設計は無理があります。逆に言えば、メモリモジュール、CPU、グラフィックスカードのどれかが壊れても他の部分が使えなくなるわけではないので、上位モジュールと下位モジュールの両方を抽象化に依存させる必要があります。問題がある場合は、直接交換するか、これに基づいて確認および変更できます。

2 番目の文は次のように理解できます: たとえば、5 つのフォン ノイマン コンポーネントを備えたマザーボードを使用しています. ある日、メモリ モジュールが壊れて交換する必要があるとします. ここでは、マザーボード全体ではなく、メモリ モジュールを交換します. マザーボードにはメモリ モジュールのインターフェイスがあり、特定のブランドが独自のインターフェイスを作成するのではなく、製造元がこのインターフェイスに従ってメモリ モジュールを製造する必要があります。交換されます。したがって、ここでのメモリースティックの内部設計 (ストレージ粒子、回路設計など) はすべて内部パッケージ (詳細) であり、これはメモリースティック設計のゴールデンフィンガーインターフェース (抽象) に依存する必要があるため、原理は依存関係の逆転: 抽象化 (メモリ インターフェイス) は詳細 (メモリ モジュールの内部パッケージング)に依存してはならず詳細 (メモリ モジュールの内部パッケージング) は抽象化 (メモリ モジュールのインターフェイス)に依存する必要があります。

過結合の代表的な例がラジオですが、ラジオが故障すると、それを理解していない人には直せません。

依存関係の逆転はオブジェクト指向設計の特徴であり、プログラム内のすべての依存関係は抽象クラスまたはインターフェイスによって終了します。


4. リスコフ置換原理 (LSP)

リスコフ置換原理 (LSP):

Liskov 置換原理は継承と再利用の基礎です. ソフトウェアエンティティが親クラスを使用する場合, それはそのサブクラスで使用されなければならず, 親クラスのオブジェクトとサブクラスのオブジェクトの違い, つまり , を検出することはできません.親クラスをそのサブクラスに置き換えても、プログラムの動作は変わりません。サブタイプはスーパータイプを置き換えることができなければなりません

サブクラスは、親クラスが表示される任意の場所を置き換えることができます. たとえば、おばあちゃんの家で働く父親を表すことができます.

サブクラスは親クラスの機能を拡張することはできますが、親クラスの元の機能を変更することはできません。


5. インターフェース分離の原則 (ISL)

インターフェース分離 (分離) 原則 (インターフェース分離原則、ISL と呼ばれる):

クラスの別のクラスへの依存は、最小の interface に基づく必要があります。

  • クラスは、必要のないインターフェースに依存すべきではありません。各インターフェースには、サブクラスが使用できないが実装する必要があるメソッドはありません。それ以外の場合は、インターフェースを分割する必要があります。
  • インターフェイスの粒度は可能な限り小さくする必要があります. インターフェイスにメソッドが多すぎる場合は、複数のインターフェイスに分割できます.

複数の専用インターフェイスを使用することは、単一の汎用インターフェイスを使用することよりも優れています. インターフェイス分離の原則は、インターフェイスを制約し、クラスのインターフェイスへの依存を減らすことです.


6. デメテルの原理 (LOD)

デメテルの法則 (デメテルの法則、LoD と呼ばれる): 最小知識の原則としても知られています。

2 つのクラスは、互いに直接通信する必要がない場合、直接対話するべきではありません。クラスの 1 つが別のクラスのメソッドを呼び出す必要がある場合、その呼び出しはサード パーティによって転送される可能性があります。クラスは、他のクラスと関係を持たないようにする必要があります

  • クラスが他のクラスについて知らないほど、結合は少なくなります。
  • 1 つのクラスが変更されると、他のクラスへの影響が少なくなり、エラーが発生する可能性が低くなります。

クラス構造の設計に関しては、各クラスはそのメンバーのアクセス権を最小限に抑える必要があります.最小知識の原則は、クラス間の結合を強調します. クラス間の結合が弱いほど、再利用が容易になり、結合が弱いクラスを変更しても、関連するクラスには影響しません。


7. 構成的再利用の原則 (CARP)

複合/集約再利用の原則 (CARP):
継承の代わりに合成/集約を使用してみてください。
親クラスと子クラスの作成者が同一人物(クラス)の場合、継承はさりげなく使われます。親クラスとサブクラスの作成者が同一人物でない場合は、構成が優先されます。継承によって不要なメソッドがいくつか持ち込まれるため、特定のクラスのメソッドを再利用する場合にのみ合成が推奨されます。


7 つの原則の要約:

Open Closed Principle (OCP):拡張のためにオープン、変更のためにクローズ

単一責任の原則 (SRP):クラスには単一の責任があります。

Dependency Induced (DIP):インターフェイスへのプログラミング

インターフェースの分離 (ISL):設計インターフェースは簡潔でシンプルでなければなりません

デメテルの原理 (LOD):クラス間の結合を減らす

構成再利用の原則 (CARP):継承の代わりに構成/集約を使用します。

デザインパターンで解決すべき問題は、
アプリケーションの可能な変更を見つけ出し、それらを分離し、変更する必要のないコードと混在させないこと、実装のためではなく、インターフェースのためにプログラムすること
です疎結合設計を目指します。

おすすめ

転載: blog.csdn.net/qq_42242452/article/details/124635739