「継ぎ目」という言葉の理解に関する問題


20

私はMark Seemannによる「.NETでの依存性注入」を読んでいます(それは素晴らしいですし、必需品です)。著者はよく「seam」という言葉を使用します。しかし、私はそれが何を意味するのか理解できません。この単語の使用例を次に示します。

第7章では、ASP.NET MVC、WPF、WCFなどのさまざまな具体的なフレームワークでオブジェクトを構成する方法について説明します。すべてのフレームワークがDIを同等にサポートしているわけではありません。また、DIをサポートしているフレームワークであっても、その方法は大きく異なります。各フレームワークについて、そのフレームワークでDIを有効にするSEAMを特定することは困難です。ただし、そのSEAMが見つかると、この特定のフレームワークを使用するすべてのアプリケーションのソリューションが得られます。第7章では、最も一般的な.NETアプリケーションフレームワークに対してこの作業を行いました。フレームワークSEAMSのカタログと考えてください。

この言葉を理解するのを手伝ってくれて感謝しています。


3
著者のブログには、この言葉の意味に関するヒントがあります。そして、彼はここにいるので:@MarkSeemannこれはあなたのためです:)
ヤンニス

回答:


25

この用語は、ソフトウェアの2つの部分が出会う場所であり、他の何かを注入できる場所としてソフトウェアの継ぎ目を説明する、Michael Feathers がLegacy Code効果的に使用していることに由来すると思います。類推は、衣服の縫い目です。2つの部分を縫い合わせる場所です。両側のピースは、縫い目でもう一方にのみ接触します。ソフトウェアに戻る:継ぎ目を特定する場合、明確に定義されたインターフェースがある場所を特定しました。そのようなインターフェイスを使用すると、ソフトウェアの残りの部分に通知せずに(とにかく不正行為をせずに)実装を置き換えることができるため、DIで活用できます。


7
c2.com/cgi/wiki?SoftwareSeam-本を持っていない人のためのリファレンスとして。
ヤニス

私は今その本を読んでいます!
マルフィスト

10
1 FWIW、私は22ページのセクション1.3.1における概念を導入
マーク・シーマン

13

クリスチャンの答えに基づいて、私の知る限り、シームという用語はフェザーズの著書「レガシーコードを効果的に使用する」に由来しています。定義は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. 注入されるクラスはfinalです。
  2. 呼び出されるメソッドは最終的なものです。

基本的に、縫い目は単体テストを容易にします。私はのためのユニットテストを書くことができないMyClassための呼び出しMyStaticClass.staticCall()(new MyInstanceClass()).instanceCall()MyClassdoBunchOfStuff()メソッドの単体テストでは、テストする必要がMyStaticClass.staticCall()あり(new MyInstanceClass()).instanceCall()、呼び出されるすべての依存関係をテストする必要があります。逆に、非ファイナルメソッド(または、さらに優れた-インターフェース)で非ファイナルクラスを使用することにより、インジェクションされたインスタンスはFoo、モックを促進することにより、書き込み可能なBarFactoryユニットテストMyClassを作成します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.