ホームページ  >  記事  >  Java  >  Java におけるオブジェクト指向設計の 6 つの原則とは何ですか?

Java におけるオブジェクト指向設計の 6 つの原則とは何ですか?

WBOY
WBOY転載
2023-05-02 08:07:061374ブラウズ

単一責任の原則

単一責任原則の定義は、クラスの変更理由は 1 つだけであるべきであるということです。言い換えれば、クラスは 1 つのことのみを担当する必要があります。クラスが 2 つの異なるもの (メソッド M1 とメソッド M2) を担当する場合、M1 メソッドが変更されると、このクラスの M1 メソッドを変更する必要がありますが、この時点では M2 メソッドが機能しない可能性があります。これは私たちが予想していたものではありませんが、この設計により可能性は十分にあります。したがって、この時点では、M1 メソッドと M2 メソッドを 2 つのクラスに分離する必要があります。各クラスは、それ自体のメソッドのみに焦点を当てます。

単一責任の原則の利点は次のとおりです:

これにより、クラスの複雑さが軽減されます。各クラスは 1 つの責任だけを負います。これにより、ロジックがはるかに単純になり、クラスの読みやすさとシステムの保守性が向上します。これは、クラスの実行を妨げる他の奇妙なメソッドが存在しないためです。このクラスの意味を理解し、変更が発生した場合、このクラス内のみで変更が行われるため、変更の影響を最小限に抑えることができます。

開閉原理

オープンクローズ原則は、単一責任原則と同様、非常に基本的な一般常識の原則です。オープンクローズ原則の定義は、ソフトウェア内のオブジェクト (クラス、モジュール、関数など) は拡張に対してはオープンであるが、変更に対してはクローズされるべきであるということです。

要件が変更されるとコードを変更する必要がありますが、このとき、元のコードを変更するのではなく、元のコードを拡張することを試みるべきです。これは、より多くの問題を引き起こす可能性があるためです。

この原則は単一責任原則と同じで、誰もがそう思っているが、具体的にどうするかは定めていない原則です。

開始と終了の原則を一方向で確保し、抽象化を使用してフレームワークを構築し、詳細を拡張する実装を使用します。このように、変更が発生した場合、抽象化を直接使用して、変更を実装する具体的なクラスを派生します。

リヒター置換原理

リスコフ置換原理は非常に便利な概念です。彼の定義

型 T1 のすべてのオブジェクト o1 に対して型 T2 のオブジェクト o2 が存在し、すべてのオブジェクト o1 が o2 に置き換えられても、T1 で定義されたすべてのプログラム P の動作が変わらない場合、型 T2 は型のサブタイプになります。 T1。

これを言うのは少し複雑ですが、実際には簡単な定義があります

基本クラスへのすべての参照は、そのサブクラスのオブジェクトを透過的に使用できなければなりません。

平たく言えば、リスコフ置換原則は次のとおりです。サブクラスは親クラスの機能を拡張できますが、親クラスの元の機能を変更することはできません。次の意味が含まれます:

サブクラスは親クラスの抽象メソッドを実装できますが、親クラスの非抽象メソッドをオーバーライドすることはできません。

サブクラスは独自の一意のメソッドを追加できます。

サブクラス メソッドが親クラス メソッドをオーバーライドする場合、メソッドの仮パラメータは親クラス メソッドの入力パラメータよりも緩くなります。

サブクラスのメソッドが親クラスの抽象メソッドを実装する場合、メソッドの戻り値は親クラスの戻り値よりも厳しくなります。

リスコフ置換原則がこれを要求する理由は、継承には多くの欠点があり、コードを再利用する方法ではありますが、継承はある程度カプセル化に違反します。親クラスの属性とメソッドはサブクラスに対して透過的であり、サブクラスは親クラスのメンバーを自由に変更できます。これにより、要件が変更され、サブクラスが親クラスの一部のメソッドをオーバーライドした場合、他のサブクラスが適切に動作しなくなります。そこでリヒター置換規則が提案されました。

プログラムがリスコフ置換原則に従っていることを確認するには、プログラムが抽象化を確立し、抽象化を通じて仕様を確立し、実装を使用して詳細を拡張する必要があります。これには馴染みがありますか? はい、リスコフ置換原則と開始および終了原則は相互依存していることがよくあります。

依存関係逆転の原理

依存関係反転の原則は、高レベルのモジュールが低レベルのモジュールの実装の詳細に依存しないように、依存関係のモジュールが反転されるように、特別な切り離し方法を指します。これも理解するのが難しい定義ですが、単純に言うと

となります。 高レベルのモジュールは低レベルのモジュールに依存すべきではありません。両方ともその抽象化に依存する必要があります。抽象化は詳細に依存すべきではありません。詳細は抽象化に依存する必要があります。

Java では、抽象化はインターフェイスまたは抽象クラスを指しますが、どちらもインスタンス化できません。詳細は実装クラスです。これは、インターフェイスを実装するクラス、または抽象クラスを継承するクラスです。インスタンス化することができます。高レベル モジュールは呼び出し側を指し、低レベル モジュールは特定の実装クラスを指します。 Java では、依存関係逆転の原理により、モジュール間の依存関係は抽象化を通じて発生し、実装クラス間には直接的な依存関係はなく、インターフェースを通じて実現されます。これは一般にインターフェイス指向プログラミングとして知られています。

この問題を説明するための例を以下に示します。この例は、作業者がハンマーを使って何かを修理している例です。コードは次のとおりです:

パブリック クラス ハンマー {

パブリック文字列関数(){

return "ハンマーを使って物を修理してください";

}

}

パブリック クラス Worker {

パブリックボイド修正(ハンマーハンマー){

System.out.println("Worker" Hammer.function());

}

public static void main(String[] args) {

新しいワーカー()。 fix(new Hammer());

}

}

これは非常に単純な例ですが、新しい機能を追加する場合、作業者がドライバーを使って修理することになりますが、このクラスではそれが困難であることがわかります。これは、Worker クラスが特定の実装クラス Hammer に依存しているためです。そこで、インターフェイス指向プログラミングの考え方を使用して、次のコードに変更します。 パブリック インターフェイス ツール {

パブリック文字列関数();

}

次に、ワーカーはこのインターフェイスを通じて他の詳細クラスに依存します。コードは以下のように表示されます:

パブリック クラス Worker {

public void fix(ツールツール){

System.out.println("Worker" tools.function());

}

public static void main(String[] args) {

新しいワーカー()。 fix(new Hammer());

新しいワーカー()。 fix(新しいドライバー());

}

}

Hammer クラスと Screwdriver クラスはこのインターフェイスを実装します

パブリック クラス Hammer はツールを実装します{

パブリック文字列関数(){

return "ハンマーを使って物を修理してください";

}

}

パブリック クラス Screwdriver はツールを実装します{

@オーバーライド###### public String function() {

return "何かを修復するにはドライバーを使用してください";

}

}

このように、インターフェース指向のプログラミングにより、コードは高い拡張性を持ち、コード間の結合が減少し、システムの安定性が向上します。

インターフェイス分離の原則

インターフェイス分離原則の定義は次のとおりです。 クライアントは、必要のないインターフェースに依存すべきではありません

つまり、クラス間の依存関係は最小のインターフェース上で確立される必要があります。理解するのがさらに難しいようです。例を挙げて説明しましょう。具象クラスが Java のインターフェイスを実装する場合、インターフェイス内のすべてのメソッドを実装する必要があることがわかっています。インターフェイス I に依存するクラス A とクラス B がある場合、クラス B はクラス A の依存関係の実装であり、このインターフェイス I には 5 つのメソッドがあります。ただし、クラス A と B はメソッド 1、2、および 3 にのみ依存し、クラス C と D はインターフェイス I に依存します。クラス D はクラス C への依存関係の実装ですが、メソッド 1、4、および 5 に依存します。次に、インターフェイスを実装するときに、クラス B は必要のないメソッド 4 とメソッド 5 を実装し、クラス D は必要のないメソッド 2 とメソッド 3 を実装する必要があります。これは単なる災害時のデザインです。

そこで、クラス B とクラス D は、関係のないインターフェイス メソッドを実装する必要がなく、依存関係を満たす最小のインターフェイスにインターフェイスを分割する必要があります。たとえば、この例では、インターフェイスを 3 つに分割できます。最初のインターフェイスはメソッド 1 のみを含むインターフェイス、2 番目のインターフェイスにはメソッド 2 と 3 が含まれ、3 番目のインターフェイスにはメソッド 4 と 5 が含まれます。このようにして、私たちの設計はインターフェース分離の原則を満たします。

上記の設計思想は、英語の頭文字をとってSOLID化することができ、この5つの原則を満たすプログラムもSOLIDの基準を満たしていると言えます。

ディミット原則

ディミット原則は最小知識原則とも呼ばれ、その定義は

です。 オブジェクトは、他のオブジェクトに関する最小限の知識を保持する必要があります。

クラス間の関係が緊密であればあるほど、結合の度合いは大きくなります。一方のクラスが変更されると、もう一方のクラスへの影響も大きくなります。したがって、これは、私たちが提唱するソフトウェア プログラミングの一般原則「低結合、高結合」でもあります。凝集。デメテルの法則にはもっと簡単な定義があります

直接の友人とのみ通信してください。まず、直接のフレンドとは何かというと、各オブジェクトは他のオブジェクトとカップリング関係を持ち、2 つのオブジェクト間にカップリング関係がある限り、その 2 つのオブジェクトはフレンドであると言います。結合には、依存関係、関連付け、結合、集約など、さまざまな方法があります。このうち、メンバー変数、メソッドのパラメータ、メソッドの戻り値に現れるクラスを直接の友達と呼びますが、ローカル変数に現れるクラスは直接の友達ではありません。言い換えれば、馴染みのないクラスがローカル変数としてクラス内に出現しないことが最善です。

ここでは実際の例を使って説明します。たとえば、CD が必要な場合、ビデオ店に行き、必要な CD があるかどうかを上司に尋ねます。上司は、今必要な CD は持っていないので、取りに来てくださいと言います。利用可能になったときにそれを行います。ここでは、上司がCDをどこでどのように入手したかは気にする必要はなく、上司(直接の友人)とのみコミュニケーションを取り、上司が友人からCDを入手した条件については気にしません。私たちは彼に同意しません。ボスの友人 (見知らぬ人) がコミュニケーションします。これは Dimit のアプリケーションです。端的に言えば仲介手法です。ボスを仲介者として、実際にCDを提供する担当者と連絡を取ります。

以上がJava におけるオブジェクト指向設計の 6 つの原則とは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。