はい、SOLIDは簡単にテストできるコードを設計する非常に良い方法です。短い入門書として:
S-単一責任の原則: オブジェクトは、1つのことを正確に行う必要があり、その1つのことを行うコードベース内の唯一のオブジェクトでなければなりません。たとえば、請求書などのドメインクラスを取得します。Invoiceクラスは、システムで使用される請求書のデータ構造とビジネスルールを表す必要があります。コードベース内の請求書を表す唯一のクラスである必要があります。これはさらに細分化して、メソッドには1つの目的があり、コードベース内でこのニーズを満たす唯一のメソッドである必要があると言うことができます。
この原則に従うことにより、異なるオブジェクトで同じ機能をテストするために作成する必要があるテストの数を減らすことで、デザインのテスト容易性が向上します。また、通常、単独でテストするのが簡単な機能の小さな部分になります。
O-Open / Closed Principle: クラスは拡張に対して開かれているべきですが、変更のために閉じられている必要があります。オブジェクトが存在して正常に動作したら、理想的にはそのオブジェクトに戻って新しい機能を追加する変更を加える必要はありません。代わりに、オブジェクトを派生させるか、新しいまたは異なる依存関係の実装をプラグインして、その新しい機能を提供することにより、オブジェクトを拡張する必要があります。これにより、回帰が回避されます。他の場所で既に使用されているオブジェクトの動作を変更せずに、必要なときに必要な場所で新しい機能を導入できます。
この原則を順守することで、一般的に「モック」に耐えるコードの能力が向上し、新しい動作を予測するためにテストを書き直す必要もなくなります。オブジェクトのすべての既存のテストは、拡張されていない実装でも機能するはずですが、拡張された実装を使用する新しい機能の新しいテストも機能するはずです。
L-Liskov Substitution Principle: クラスBに依存するクラスAは、違いを知らなくてもX:Bを使用できるはずです。これは基本的に、依存関係として使用するものはすべて、依存クラスから見た場合と同様の動作を持つ必要があることを意味します。短い例として、ConsoleWriterによって実装されるWrite(string)を公開するIWriterインターフェイスがあるとします。ここで、代わりにファイルに書き込む必要があるため、FileWriterを作成します。その際、FileWriterがConsoleWriterと同じ方法で使用できることを確認する必要があります(つまり、Dependentが対話する唯一の方法はWrite(string)を呼び出すことです)。したがって、FileWriterが必要とする追加情報ジョブ(書き込み先のパスやファイルなど)は、依存関係以外の場所から提供する必要があります。
これは、テスト可能なコードを記述するのに非常に大きなことです。LSPに準拠する設計では、予測される動作を変更せずに、実物の代わりに「モック」オブジェクトを使用できるため、小さなコードを自信を持って単独でテストできます。システムはプラグインされた実際のオブジェクトで動作します。
I-インターフェースの分離の原則: インターフェースは、インターフェースによって定義された役割の機能を提供するために可能な限り少ないメソッドを持っている必要があります。簡単に言えば、少数の大きなインターフェースよりも小さなインターフェースの方が優れています。これは、大きなインターフェイスには変更の理由が多く、コードベースの他の場所で必要でない可能性のある変更が多くなるためです。
ISPを順守することで、テスト対象のシステムとそれらのSUTの依存関係の複雑さを軽減することにより、テスト容易性が向上します。テストするオブジェクトがDoOne()、DoTwo()、DoThree()を公開するインターフェイスIDoThreeThingsに依存する場合、オブジェクトがDoTwoメソッドのみを使用している場合でも、3つのメソッドすべてを実装するオブジェクトをモックする必要があります。ただし、オブジェクトがIDoTwo(DoTwoのみを公開する)のみに依存する場合、その1つのメソッドを持つオブジェクトをより簡単にモックできます。
D-依存性反転の原理: 結石と抽象化は他の結石に決して依存せず、抽象化に依存するべきです。この原則は、疎結合の原則を直接実施します。オブジェクトは、オブジェクトが何であるかを知る必要はありません。代わりに、オブジェクトが何をするかを気にする必要があります。そのため、オブジェクトやメソッドのプロパティやパラメータを定義するときは、具体的な実装の使用よりも、インターフェースや抽象基底クラスの使用を常に優先する必要があります。これにより、使用方法を変更することなく、1つの実装を別の実装に交換できます(DIPと連動するLSPも使用する場合)。
繰り返しになりますが、これはテスト対象のオブジェクトに「本番」実装の代わりに依存関係のモック実装を挿入することができるため、テスト可能性にとって非常に大きなものです。生産中。これは、「単独で」単体テストを行うための鍵です。