やがて、私は [〜#〜] solid [〜#〜] の2つの部分、「S」と「O」を理解することができました。
「O」–継承と戦略パターンの助けを借りて、オープンクローズの原則を学びました。
「S」– ORMの学習中に単一責任の原則を学びました(永続化ロジックはドメインオブジェクトから削除されています)。
同様に、SOLID(「L」、「I」、「D」)の他の部分を学習するのに最適な領域/タスクは何ですか?
参考文献
非常に役立つ記事が見つかるまで、数か月前に私はあなたの立場に立っていました。
各原則は、各ソフトウェア開発者がプロジェクトで直面する可能性がある実際の状況でうまく説明されています。私はここで短くして、参照を示しています- S.O.L.I.D。ソフトウェア開発、一度に1つのステップ 。
コメントで指摘されているように、別の非常に優れたpdfの読みがあります- PabloのSOLIDソフトウェア開発 。
さらに、SOLID原則の詳細を説明した優れた書籍がいくつかあります Good Book on SOLID Software Development 。
各原則の短い要約の編集とコメント:
「S」–単一の責任原則は、変化を可能にするビジネスのニーズによって推進されます。 「変更する単一の理由」は、技術的な概念だけではなく、ビジネスの概念とコンテキストを考慮することによって、論理的に分離された概念をグループ化する必要があることを理解するのに役立ちます。 In another words
、私は各クラスが単一の責任を持つべきであることを学びました。責任は割り当てられたタスクを達成することです
「O」–私はOpen Closed Principleを学び、「継承よりもコンポジションを優先する」ようになりました。そのため、仮想メソッドがなく、おそらくシールされているが、それらの拡張は抽象化に依存しているクラスを優先します。
「L」–私は、データアクセスを管理するためのリポジトリパターンの助けを借りて、リスコフの置換原理を学びました。
CodePlexからの有用なリソースがコメントで言及されたので、参照が含まれています 例ではSOLID
(I)インターフェースの分離と(D)依存関係の逆転は、単体テストとモッキングによって学習できます。クラスが独自の依存関係を作成すると、適切な単体テストを作成できません。それらが広すぎるインターフェースに依存している(またはインターフェースがまったくない)場合、単体テストを作成するために何をモックする必要があるかはあまり明確ではありません。
Liskov Substitution Principle基本的に、実装の継承を使いすぎないようにします。継承をコードの再利用のためだけに使用することはできません(これには構成があります)。 LSPに準拠することで、スーパークラスとサブクラスの間に「is-a関係」が実際に存在することをかなり確信できます。
つまり、サブクラスは、サブクラスのメソッドの実装と同様の方法で、サブクラスのすべてのメソッドを実装する必要があります。スーパータイプが例外をスローしたときに、NOPを実装してメソッドをオーバーライドしたり、nullを返したりしないでください。 Design by Contractの条件で述べられているように、メソッドをオーバーライドするときは、スーパークラスからのメソッドの契約を尊重する必要があります。この原則を破らないようにする方法は、実装されたメソッドをオーバーライドしないことです。代わりに、インターフェースを抽出し、両方のクラスにそのインターフェースを実装します。
インターフェース分離の原則、単一の責任の原則とGRASPの高コーシオンの原則は何らかの形で関連しています。それらは、変更が非常に簡単に行われるように、変更の理由が1つだけあるように、エンティティが1つのことだけを担当する必要があるという事実を参照します。
実際には、クラスがインターフェースを実装する場合、それらのインターフェースのメソッドをすべて実装して使用する必要があると述べています。その特定のクラスで必要のないメソッドがある場合、インターフェースは適切ではなく、元のクラスで必要なメソッドのみを持つ2つのインターフェースに分割する必要があります。これはPOVと見なすことができます。POVは、大規模なインターフェイスを作成できないため、その実装によってLSPが無効になる可能性があるという事実から、以前の原則に関連しています。
ファクトリパターンでDependency Inversionを確認できます。ここでは高レベルコンポーネント(クライアント)と低レベルコンポーネント(作成される個々のインスタンス)は、抽象化(インターフェース)に依存します。レイヤードアーキテクチャでそれを適用する方法:実装されているレイヤーではなく、呼び出されたモジュールでレイヤーへのインターフェイスを定義するべきではありません。たとえば、データソースレイヤーへのAPIは、データソースレイヤーではなく、呼び出しが必要なビジネスロジックレイヤーに書き込む必要があります。このようにして、データソースレイヤーは、ビジネスロジックで定義された動作(したがって反転)を継承/依存し、その逆(通常の方法のように)ではありません。これにより、設計に柔軟性がもたらされ、コードを変更することなく、まったく別のデータソースを使用してビジネスロジックを機能させることができます。