2009-09-21 8 views
7

Wikipedia besagt, dass das Spezifikationsmuster die Geschäftslogik neu kombinieren kann, indem die Geschäftslogik mithilfe von Boolescher Logik verkettet wird. In Bezug auf die Auswahl von Filterobjekten aus Listen oder Sammlungen scheint mir, dass Dynamic LINQ mir ermöglicht, dasselbe zu erreichen. Fehle ich etwas? Gibt es weitere Vorteile für das Spezifikationsmuster, die ebenfalls berücksichtigt werden sollten?Ist das Spezifikationsmuster veraltet, wenn Sie Dynamic LINQ verwenden können?


Edit:

ich einige Beiträge gefunden haben, die LINQ und die Spezifikation Muster discuss Kombination:

Linq Specifications Project

Implementing the Specification Pattern via Linq by Nicloas Blumhardt (Autofac dude)

ist gegangen jemand diesen Weg gemacht und tat es wird kompliziert zu pflegen?

+0

Ich bin gerade mit dieser exakten Situation konfrontiert, daher ist diese Frage für mich von großem Interesse. –

Antwort

2

Dynamischer LINQ verwendet Zeichenfolgenausdrücke, um die dynamische Abfragekonstruktion zu ermöglichen. Wir verlieren also dort die Typsicherheit. Während Wrapper-Muster wie das Decorator-Muster der eng verwandten Inkarnation, das Spezifikationsmuster, uns erlauben, die Typsicherheit im Code beizubehalten. Ich erkunde das Decorator Pattern als Abfrage-Wrapper, um Abfragen wiederzuverwenden und dynamisch aufzubauen. Sie können den Artikel über Code-Projekt finden: Linq Query Wrappers

Oder Sie können meine blog überprüfen.

5

Ich bin ein C# -Entwickler und möchte das Spezifikationsmuster verwenden, weil es näher an meiner Geschäftsdomäne ist. Außerdem überrascht Sie dieses Muster nicht, wenn eine Spezifikationsklasse existiert, sollte es funktionieren. Mit Linq hat der zugrunde liegende Anbieter möglicherweise einige Funktionen nicht implementiert und Sie werden es erst zur Laufzeit wissen.

Aber definitiv ist der größte Vorteil der Spezifikation über linq näher am Geschäft zu sein, es ist ein Mini-DSL. LINQ ist für mich eine Abfrage für DSL für die Sammlung, nicht für die Geschäftsdomäne.

1

Ich kenne LINQ nicht wirklich, aber es scheint mir, dass ein deklaratives Abfragesystem im Allgemeinen mit dem Spezifikationsmuster verwandt ist. Insbesondere das Implementieren eines deklarativen Abfragesystems durch Zusammensetzen von Objekten in einer objektorientierten Umgebung. IIRC, das dem von LINQ ähnelt und eine Schicht syntaktischen Zuckers bereitstellt.

Ob LINQ das Muster vollständig veraltet, kann ich nicht sagen. Vielleicht gibt es Eckfälle, die in LINQ einfach nicht ausgedrückt werden können?

0

LINQ:

var oldMans = Persons.Where(x => x.Sex == SexEnum.Masculine && x.Age > 60).ToList(); 

Spezifikation:

var oldMans = Persons.Where(x => IsOldManSpecification(x)).ToList(); 
  • Die Geschäftslogik ist in der Beschreibung abgekapselt (mit einem Namen, offenbaren, was es ist).
  • DRY: Sie wiederholen nicht, dass Linq über den Code, verwenden Sie einfach die Spezifikation

Ich mag Spezifikation verwenden, wenn ich denke, dass die Regel wichtig genug ist, um den Code zu seinen explizit BUT es gehört nicht zu der Einheit.

Beispiel:

public class Customer 
{ 
    //... 

    public bool IsAbleToReceiveCredit(decimal creditValue) 
    { 
     var secureAge = this.Age > 18 && this.Age < 60; 
     var personalAssetsGreaterThanCreditValue = this.PersonalAssets.Sum(x => x.Value) > creditValue; 

     return secureAge && personalAssetsGreaterThanCreditValue; 
    } 
} 

Ist es aus dem Customer die responsability zu entscheiden, ob er in der Lage ist, einen Kredit zu erhalten?

Wahrscheinlich nicht.

Also mit der Spezifikation können Sie diese Logik aus dem Customer entfernen (es gehörte nie dazu). Sie können so etwas wie IsAbleToReceiveCreditSpecification erstellen und alle Logik dort platzieren. Wir können weiter gehen und Spezifikationen kombinieren, zum Beispiel: Sie könnten eine SecureAgeSpecification und eine AssetsGreaterThanSpecification erstellen und sie verwenden, um die IsAbleToReceiveCreditSpecification zu komponieren.

Also ich glaube nicht, dass LINQ die Spezifikation ersetzt. Tatsächlich verbessert es das Muster. Es gibt einige Implementierungen von Specification, die LINQ intern mit IQueriable<T> verwenden. Damit können Sie die Spezifikation in Ihren ORM-Abfragen auf der Repository/DataAccess-Ebene verwenden.