2009-09-21 13 views
7

Wikipedia indique que le modèle de spécification est l'endroit où la logique métier peut être recombinée en enchaînant la logique métier en utilisant la logique booléenne. En ce qui concerne la sélection des objets de filtrage à partir de listes ou de collections, il me semble que Dynamic LINQ me permet d'accomplir la même chose. Est-ce que je manque quelque chose? Y a-t-il d'autres avantages au modèle de spécification qui devraient également être pris en compte?Le modèle de spécification est-il obsolète lorsque vous pouvez utiliser Dynamic LINQ?


Edit:

J'ai trouvé quelques messages que discuter Demandé combinant LINQ et le motif Spécification:

Linq Specifications Project

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

Quelqu'un at-gone fait cette route et a fait cela devient compliqué à maintenir?

+0

Je suis à peu près dans la situation actuelle, donc cette question m'intéresse beaucoup. –

Répondre

2

Dynamic LINQ utilise des expressions de chaîne pour autoriser la construction de requête dynamique. Nous perdons donc la sécurité de type là-bas. Alors que l'utilisation de modèles d'encapsulation comme le motif décoratif de l'incarnation étroitement liée, le modèle de spécification, nous permet de maintenir le type de sécurité dans le code. J'explore l'utilisation du motif de décorateur comme enveloppe de requête afin de réutiliser et de générer dynamiquement des requêtes. Vous pouvez trouver l'article sur le projet de code à: Linq Query Wrappers

Ou vous pouvez vérifier mon blog.

5

Je suis un développeur C# et j'aime utiliser le modèle de spécification, car il est plus proche de mon domaine d'activité. De plus, vous n'avez pas de surprise avec ce modèle, si une classe de spécification existe, cela devrait fonctionner. Avec Linq, votre fournisseur sous-jacent n'a peut-être pas implémenté certaines fonctionnalités, et vous ne le saurez pas avant l'exécution.

Mais définitivement, le plus grand avantage de la spécification par rapport à linq est d'être plus proche de l'entreprise, c'est un mini DSL. LINQ pour moi est un DSL pour la requête de collection, pas pour le domaine d'affaires.

1

Je ne connais pas réellement LINQ, mais il me semble qu'un système de requête déclaratif en général est lié au modèle de spécification. En particulier, implémenter un système de requête déclaratif en composant des objets ensemble dans un environnement orienté objet. IIRC s'apparente à ce que fait LINQ en fournissant une couche de sucre syntaxique.

Si LINQ obsolète complètement le modèle, je ne peux pas le dire. Peut-être qu'il y a des cas de coin qui ne peuvent tout simplement pas être exprimés dans LINQ?

0

LINQ:

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

Spécification:

var oldMans = Persons.Where(x => IsOldManSpecification(x)).ToList(); 
  • La logique métier est encapsulé dans la spécification (avec un nom qui révèle ce qu'il est).
  • DRY: vous ne répétez pas que LINQ sur le code, il vous suffit d'utiliser la spécification

J'aime utiliser la spécification quand je pense que la règle est suffisamment important pour être explicite dans le code, mais il n'appartient pas à l'entité.

Exemple:

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

est-il de la Customer la responsabilité de décider si lui est en mesure de recevoir un certain crédit?

Probablement pas. Donc, avec les spécifications, vous pouvez supprimer cette logique du Customer (il n'y a jamais appartenu). Vous pouvez créer quelque chose comme IsAbleToReceiveCreditSpecification et y mettre toute la logique. Nous pouvons aller plus loin et combiner les spécifications, par exemple: vous pouvez créer un SecureAgeSpecification et un AssetsGreaterThanSpecification et les utiliser pour composer le IsAbleToReceiveCreditSpecification. Donc je ne pense pas que LINQ remplace la spécification. En fait, cela améliore le modèle. Il existe certaines implémentations de spécification qui utilisent LINQ en interne avec IQueriable<T>, avec ceci vous pouvez utiliser la spécification dans vos requêtes ORM au niveau Repository/DataAcess.