7

Ich mache einige R & D Arbeit, und als solche erkundet Design-Muster. Ich habe kürzlich über das Spezifikationsmuster gelesen und wurde auf this großen Artikel verwiesen.Vergleich der Spezifikation Muster, Func <T,bool> Prädikate und Rohre und Filter

Ich war fasziniert von der Einfachheit und Sauberkeit des Codes, aber ich fing an, einige Vergleiche zu ziehen, um die gleiche Sauberkeit mit anderen Techniken zu implementieren.

Betrachten Sie die folgende Schnittstellenvertrag für eine Dienstschicht:

public interface IFooDataService 
{ 
    ICollection<Foo> GetFoosBySpecification(Specification<Foo> specification); 
    ICollection<Foo> GetFooByPredicate(Func<Foo,bool> predicate); 
    ICollection<Foo> GetFooBySearchArgs(FooSearchArgs searchArgs); 
} 

Also, einige Ausgangspunkte:

  • Alle drei Rückkehr eine Sammlung von Foo-Objekte
  • Alle drei ein einziges Argument
  • Spezifikation Methode beschränkt den Zugriff auf bestimmte Anforderungen
  • Prädikats Methode hat im Grunde keine Einschränkung
  • Suche args Methode den Zugriff auf bestimmte Anforderungen beschränkt

nun auf die Umsetzung:

public ICollection<Foo> GetFoosBySpecification(Specification<Foo> specification) 
{ 
    return fooDataRepository 
      .Find() 
      .Where(f => specification.IsSatisfiedBy(f)) 
      .ToList(); 
} 

public ICollection<Foo> GetFooByPredicate(Func<Foo, bool> predicate) 
{ 
    return fooDataRepository 
      .Find() 
      .Where(predicate) 
      .ToList(); 
} 

public ICollection<Foo> GetFooBySearchArgs(FooSearchArgs searchArgs) 
{ 
    return fooDataRepository 
      .Find() 
      .WhereMeetsSearchCriteria(searchArgs) 
      .ToList(); 
} 

Punkte über die Umsetzung:

  • Alle drei sind in der Implementierung extrem einfach (eine Linie des verketteten Codes)
  • Spe cification und Search Args gefiltert extern implementiert.
  • Suche args Verfahren verwendet einfach IEnumerable-Extension-Methode args So

zu inspizieren, dass, verwenden Sie eine der oben genannten drei Techniken würden Bedingungen, unter welchen gesagt wird?

Meine Gedanken über Muster Spezifikation:

  • Nizza, dass sie isoliert Business/Domain-Anforderungen in wiederverwendbare Komponenten
  • Extrem leicht zu lesen, Code sprechen Englisch
  • Messe Stück Code beteiligt (Schnittstellen macht , abstrakte Klassen). Wenn ich das verwenden würde, würde ich die Abstraktionen in eine gemeinsame Assembly setzen (also habe ich keine Menge von statischen Dateien in meiner Lösung).
  • Einfach die Anforderungen zu ändern, indem nur die Spezifikation geändert wird und nicht die Serviceebene.
  • Supreme Testbarkeit von Domain-Logik (Spezifikationen)

Meine Gedanken über Erweiterungsmethoden (Pipes & Filter):

  • 'Gewichtiges' in der Logik, aber immer noch in der gleichen Einfachheit führen.
  • Isolat Abfragelogik von Service-Layer zu statischen Methoden
  • erfordert Still „Reflexion“ von sort (geliefert Suche args Inspektion und Abfrage Aufbau)
  • Ermöglicht der Code-Architektur (Repository, Service-Layer) zuerst, ohne zu denken über spezifische Geschäftsanforderungen

Meine Gedanken auf Prädikats-Methode (die in bestimmten Szenarien praktisch ist): verwendet grobkörnigem Co, wo Sie brauchen werden

  • Könnte über die Abfragen steuern.
  • Gut für kleine Projekte, in denen Spezifikationen es
übertreiben können, ist meine letzten Gedanken Logik

dass, wenn Sie auf einer komplexen Business-Anwendung arbeiten, in dem sie vorne Geschäftsanforderungen bekannt, aber im Laufe der Zeit ändern, ich dann würde Spezifikationsmuster verwenden.

Aber für eine Anwendung, die ein "Startup" ist, dh Anforderungen im Laufe der Zeit entwickelt und hat eine Vielzahl von Möglichkeiten, Daten ohne komplexe Validierung abrufen, würde ich die Pipes und Filter-Methoden verwenden.

Was sind Ihre Gedanken? Hat jemand von Ihnen Probleme mit einer der oben genannten Methoden? Irgendwelche Empfehlungen?

Über ein neues Projekt zu starten, so dass diese Art von Überlegungen kritisch sind.

Danke für die Hilfe.

EDIT für Klärung Muster Spezifikation

ist hier gleiche Verwendung der Spezifikation Muster.

Specification<Foo> someSpec; // Specification is an abstract class, implementing ISpecification<TEntity> members (And, Or, Not, IsSatisfiedBy). 
someSpec = new AllFoosMustHaveABarSpecification(); // Simple class which inherits from Specification<Foo> class, overriding abstract method "IsSatisfiedBy" - which provides the actual business logic.  
ICollection<Foo> foos = fooDataService.GetFoosBySpecification(someSpec); 
+0

Es ist nicht ganz klar, wie 'Specification ' sich von 'Func ' unterscheidet. – Gabe

+0

@Gabe - ich wollte nicht Code über die Art und Weise, wie das Spezifikationsmuster implementiert wird, als a) seine viel Code (4 Klassen) und b) die Verbindung, die ich zur Verfügung gestellt habe, um die Implementierungsdetails bereitzustellen. – RPM1984

+0

Ich lese den Link; Ich sehe den semantischen Unterschied einfach nicht. – Gabe

Antwort

2

Von meiner kleinen Erfahrung:

  1. Benutzeranforderung immer ändern, und ich weiß nicht, warum immer mein Chef ermöglicht, dass Änderungen zu kommen. Also +1 zu Spezifikation
  2. Programmierer hier ist mehr wie "Arbeiter" als "Wissensarbeiter". Du weißt .. derjenige, der den ganzen Tag lang schreibt. Durch die Verwendung von Specification kann ich mir selbst versichern, dass jeder "typisiert". Dies wird durch die Art meines Projekts unterstützt. Es benötigt viele verschiedene Implementierungen für den gleichen Zweck. Frag mich nicht warum.
  3. Verwenden Sie ein Designmuster, das Ihnen höchste Modularität und Flexibilität und natürlich Testbarkeit bietet. Hier ist eine kleine Geschichte.
    An einem schönen Tag erzählte mir mein Kumpel, dass er eine Klasse geschrieben habe, die es uns ermöglichte, 32 Arten der Berechnung von X zu berechnen. Und das alles hat er bereits umgesetzt. Hoho, das war so eine heroische Programmierung, denke ich.Er verbrachte mehrere Wochen damit mitten in der Nacht. Er glaubte, dass er ein guter Programmierer war, also bestand er darauf, dass jeder sein Meisterwerk benutzte.
    Wir waren zu dieser Zeit nicht an Komponententests interessiert, also haben wir sein Meisterstück benutzt. Was ist dann passiert? Der Code ist ständig abgestürzt. Nun, von dieser Zeit an wurde mir klar, wie wichtig Komponententest und Modularität sind.
0

Nun, zunächst würde ich die Prädikats Methode schreiben, auch wenn es nur als private Implementierungsdetails für die beiden anderen verwendet wird:

private ICollection<Foo> GetFoosBySpecification(Specification<Foo> spec) 
{ 
    return GetFooByPredicate(f => spec.IsSatisfiedBy(f)); 
} 

Das Suchargument Funktion wäre eine ähnliche Ein- Liner.

Darüber hinaus kann ich wirklich nichts abstraktes sagen. Ich müsste mehr über die Datenstruktur wissen, um den besten Weg zu finden, sie zu finden.

Verwandte Themen