インターフェイスSerializer
とメソッドserialize
とisSerializerFor
があります。私はTDDを使用してこれの最初の実装を作成し、Niceクリーン実装を完全にカバーするNiceクリーンテストケースで終わりました。より具体的なアイデアを得るために、ここに 1つの関連するコミット を示します。
ここで、他の誰か(TDDに慣れていない人)が、このSerializer
インターフェースの2番目の実装の作成を開始しました。この人は、2番目の実装に必要なテストが私の最初のテストとある程度重複するだろうと考えました。そのため、すべてのシリアライザテストケースに共通していると思われるメソッドを保持する シリアライザテストの抽象基本クラス が作成されました。
これには2つの主な理由で満足できません。まず、ここで継承が使用される唯一の理由は、コードの再利用のためです。これは大きなコードの匂いです。第二に、これはTDDサイクルを壊します。 Serializer
の別の実装を作成し、基本テストクラスの派生物を作成したい場合、すべての製品コードを1つのステップで実装する必要があります。
一方、テストクラスの共通コードを単純に複製することも、かなり奇妙に思えます。ここでは、これらの問題を回避するために、正しい方法でコンポジションを使用できることを願っています。
これはかなり一般的な状況のようです。これをどのように解決しますか?どのように違うと思いますか?
まず、ここで継承が使用される唯一の理由は、コードの再利用のためです。これは大きなコードの匂いです。
異なるシリアライザー実装(SerializerA
、SerializerB
、SerializerC
など)は、異なるSerializerTest
クラス(SerializerTestA
、SerializerTestB
、SerializerTestC
)につながります。これらはすべて「シリアライザーテスター」であり、共通のSerializerTester
基本クラスへの「is-a」関係を提供するため、継承おそらくここで正しいツールです。
Serializerの別の実装を作成し、基本テストクラスの派生物を作成したい場合、すべての製品コードを1つのステップで実装する必要があります。
私はそうは思いません。テストクラスSerializerTestA
を作成してTDDを開始します(SerializerTester
オブジェクトを作成するだけでSerializerA
から派生します。これはコンパイルされません。テストはREDです。次にSerializerA
を実装するのは、Serializer
のコンストラクターと空のメソッド実装だけです。インターフェース-テストは緑です。次に、最初のテストメソッドをSerializerTestA
に追加します。これにより、テストコールがSerializerTester
の対応するメソッドに委任される場合があります。SerializerA
の実装がないため、テストは失敗します-再度赤SerializerA
の最初の空のメソッド。最初のメソッドが失敗するまで、テストステータスは再び緑になります。
したがって、SerializerTester
クラスの完全な実装を必要とするSerializer
からテストメソッドを呼び出さない限り、従来のTDDパスを維持したまま、段階的にこれを行うことができます。