理解“接缝”一词的问题


20

我正在阅读Mark Seemann撰写的“ .NET中的依赖项注入”(这太棒了,而且必须有),并且作者经常使用“ seam”一词。但我不明白这意味着什么。这是使用此词的示例:

第7章介绍了如何在各种具体框架(例如ASP.NET MVC,WPF,WCF等)中组成对象。并非所有框架都同样出色地支持DI,即使在那些框架中,DI的实现方式也有很大差异。对于每个框架,可能很难确定在该框架中启用DI的SEAM。但是,一旦找到SEAM,您就会为使用该特定框架的所有应用程序找到一个解决方案。在第7章中,我已经为最常见的.NET应用程序框架完成了这项工作。可以将其视为框架SEAMS的目录。

感谢您帮助我理解这个词。


3
作者的博客上暗示了这个词的含义。而且,由于他是这里成员:@MarkSeemann,这是给您的:)
yannis 2012年

Answers:


25

我认为该术语源自Michael Feathers 与Legacy Code的有效合作,他在其中解释了软件中的接缝,作为软件的两个部分相遇并且可以注入其他东西的地方。类比是衣服上的接缝:将两个部分缝合在一起的地方。每侧的一块仅在接缝处碰到另一侧。返回软件:如果您标识了接缝,则说明存在定义明确的界面的位置。那就是您可以在DI中利用的功能,因为这样的接口使您可以替换实现,而软件的其余部分却无法分辨(无论如何都不作弊)。


7
c2.com/cgi/wiki?SoftwareSeam-作为没有本书的读者的参考。
yannis 2012年

我正在看那本书!
Malfist 2012年

10
+1 FWIW,我在第22页的1.3.1节中介绍了这一概念
。– Mark Seemann

13

就克里斯汀的回答为基础,据我所知,接缝一词的确源于Feathers的著作《有效地使用旧版代码》。定义在第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();
  }
}

上面示例的接缝将是接缝,除非:

  1. 正在注入的课程是最终的。
  2. 被调用的方法是最终的。

基本上,接缝有助于单元测试。我可以不写单元测试MyClass,因为调用的MyStaticClass.staticCall()(new MyInstanceClass()).instanceCall()。所有单元测试MyClassdoBunchOfStuff()方法将不得不测试MyStaticClass.staticCall()(new MyInstanceClass()).instanceCall()所有的依赖性是被调用。相反,通过将非最终类与非最终方法(或更好的接口)配合使用,可以通过简化模拟来注入的实例FooBarFactory通过MyClass编写使单元测试成为可能。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.