クリスチャンの答えに基づいて、私の知る限り、シームという用語はフェザーズの著書「レガシーコードを効果的に使用する」に由来しています。定義は31ページにあります。
シームは、その場所で編集せずにプログラムの動作を変更できる場所です。
継ぎ目とは何かの例を示すために、次のJavaコードを検討してください。
public class MyClass {
private final Foo foo;
public MyClass(Foo foo) {
this.foo = foo;
}
public void doBunchOfStuff(BarFactory barFactory) {
// foo.doStuff() is a seam because I can inject a mock instance of Foo
this.foo.doStuff();
// barFactory.makeBars() is a seam because I can replace the default
// BarFactory instance with something else during testing
List<Bar> bars = barFactory.makeBars();
for(Bar bar : bars) {
// bar.cut() is also a seam because if I can mock out BarFactory, then
// I can get the mocked BarFactory to return mocked Bars.
bar.cut();
}
// MyStaticClass.staticCall() is not a seam because I cannot replace
// staticCall() with different behavior without calling a class besides
// MyStaticClass, or changing the code in MyStaticClass.
MyStaticClass.staticCall();
// This is not a seam either because I can't change the behavior of what
// happens when instanceCall() occurs with out changing this method or
// the code in instanceCall().
(new MyInstanceClass()).instanceCall();
}
}
上記の縫い目は、次の場合を除き、縫い目です。
- 注入されるクラスはfinalです。
- 呼び出されるメソッドは最終的なものです。
基本的に、縫い目は単体テストを容易にします。私はのためのユニットテストを書くことができないMyClass
ための呼び出しMyStaticClass.staticCall()
と(new MyInstanceClass()).instanceCall()
。MyClass
のdoBunchOfStuff()
メソッドの単体テストでは、テストする必要がMyStaticClass.staticCall()
あり(new MyInstanceClass()).instanceCall()
、呼び出されるすべての依存関係をテストする必要があります。逆に、非ファイナルメソッド(または、さらに優れた-インターフェース)で非ファイナルクラスを使用することにより、インジェクションされたインスタンスはFoo
、モックを促進することにより、書き込み可能なBarFactory
ユニットテストMyClass
を作成します。