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
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);
Es ist nicht ganz klar, wie 'Specification' sich von 'Func ' unterscheidet. –
Gabe
@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
Ich lese den Link; Ich sehe den semantischen Unterschied einfach nicht. – Gabe