Building on Christian's answer, to the best of my knowledge, the term seam does originate from Feathers' book, Working Effectively with Legacy Code. The definition is on page 31:
A seam is a place where you can alter behavior in your program without editing in that place.
To give examples of what a seam is and what it isn't, consider the following Java code:
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();
}
}
The seams exemplified above would be seams unless:
- The class being injected is final.
- The method being called is final.
Basically, seams facilitate unit testing. I can't write a unit test for MyClass
because of the calls to MyStaticClass.staticCall()
and (new MyInstanceClass()).instanceCall()
. Any unit test for MyClass
's doBunchOfStuff()
method would have to test MyStaticClass.staticCall()
and (new MyInstanceClass()).instanceCall()
and all of their dependencies that get called. Conversely, by using non-final classes with non-final methods (or better yet - interfaces), the injected instances of Foo
and BarFactory
make unit tests for MyClass
possible to write by facilitating mocking.