Problem beim Verstehen des Wortes "Naht"

20

Ich lese "Dependency Injection in .NET" von Mark Seemann (es ist fantastisch und muss es sein) und der Autor verwendet oft das Wort "Naht". Aber ich kann nicht verstehen, was es bedeutet. Hier ist ein Beispiel für die Verwendung dieses Wortes:

In Kapitel 7 wird erläutert, wie Sie Objekte in verschiedenen konkreten Frameworks wie ASP.NET MVC, WPF, WCF usw. erstellen. Nicht alle Frameworks unterstützen DI gleich gut, und selbst bei denen, die dies tun, unterscheiden sich die Vorgehensweisen erheblich. Für jedes Framework kann es schwierig sein, den SEAM zu identifizieren, der DI in diesem Framework aktiviert. Sobald SEAM gefunden wurde, haben Sie jedoch eine Lösung für alle Anwendungen, die dieses spezielle Framework verwenden. In Kapitel 7 habe ich diese Arbeit für die gängigsten .NET-Anwendungsframeworks durchgeführt. Stellen Sie es sich als einen Katalog von Framework-SEAMS vor.

Ich wäre Ihnen dankbar, wenn Sie mir helfen würden, dieses Wort zu verstehen.

user278618
quelle
3
Auf dem Blog des Autors gibt es Hinweise, was das Wort bedeutet . Und da er hier Mitglied ist : @MarkSeemann ist dieser für dich :)
yannis

Antworten:

25

Ich denke, der Begriff stammt von Michael Feathers Working Effectively with Legacy Code, in dem er eine Naht in Software als einen Ort erklärt, an dem sich zwei Teile der Software treffen und an dem etwas anderes injiziert werden kann. Die Analogie ist eine Naht in der Kleidung: Die Stelle, an der zwei Teile zusammengenäht werden. Das Teil auf jeder Seite berührt das andere nur direkt an der Naht. Zurück zur Software: Wenn Sie die Naht identifizieren, haben Sie die Stelle identifiziert, an der es eine genau definierte Schnittstelle gibt. Das ist es, was Sie in DI nutzen können, da Sie mit einer solchen Schnittstelle die Implementierung ersetzen können, ohne dass der Rest der Software dies erkennen kann (jedenfalls ohne zu schummeln).

Christian Horsdal
quelle
7
c2.com/cgi/wiki?SoftwareSeam - als Referenz für diejenigen, die das Buch nicht haben.
Yannis
Ich lese gerade dieses Buch!
Malfist
10
+1 FWIW, ich stelle das Konzept in Abschnitt 1.3.1 auf Seite 22 vor.
Mark Seemann
13

Aufbauend auf Christians Antwort stammt der Begriff "Naht" meines Wissens aus Feathers 'Buch "Effective Working with Legacy Code" . Die Definition finden Sie auf Seite 31:

Eine Naht ist ein Ort, an dem Sie das Verhalten in Ihrem Programm ändern können, ohne es dort zu bearbeiten.

Betrachten Sie den folgenden Java-Code, um Beispiele zu geben, was eine Naht ist und was nicht:

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();
  }
}

Die oben beispielhaft angegebenen Nähte wären Nähte, es sei denn:

  1. Die injizierte Klasse ist endgültig.
  2. Die aufgerufene Methode ist final.

Grundsätzlich erleichtern Nähte das Testen von Einheiten. Ich kann MyClasswegen der Anrufe bei MyStaticClass.staticCall()und keinen Unit Test schreiben (new MyInstanceClass()).instanceCall(). Jede Einheit Test für MyClass‚s doBunchOfStuff()Methode müßte Test MyStaticClass.staticCall()und (new MyInstanceClass()).instanceCall()und alle ihre Abhängigkeiten , die aufgerufen. Umgekehrt ermöglichen Foound BarFactoryermöglichen die injizierten Instanzen von Unit-Tests durch die Verwendung von Non-Final-Klassen mit Non-Final-Methoden (oder besser noch - Interfaces) das MyClassSchreiben, indem sie das Verspotten erleichtern.

entpnerd
quelle