2009-11-23 3 views
13

Je voulais juste obtenir des idées de groupes sur la façon de gérer les détails de configuration des entités. À mon avis, ce sont des paramètres de haut niveau qui peuvent être modifiés par l'administrateur. Le genre de chose que vous pourriez stocker dans l'application ou web.config finalement, mais à partir de la perspective DDD devrait être définie quelque part dans les objets explicitement. À titre d'exemple, prenons comme exemple un CMS ou une application de blog basée sur le WEB.Paramètres au niveau de l'application dans DDD?

Une entité d'entrée blog donné a un certain nombre de paramètres de l'instance comme auteur, contenu, etc.

Mais vous aussi pouvez définir (par exemple) par défaut Description ou les mots clés que toutes les entrées du site devrait commencer par si elles ne sont pas modifiées par l'auteur. Bien sûr, vous pourriez simplement faire ces constantes dans la classe, mais alors le propriétaire du site ne pourrait pas changer les valeurs par défaut.

Alors mes pensées sont les suivantes:

1) utiliser les propriétés de niveau de classe (statiques) pour représenter les paramètres, puis les définir lorsque l'application démarre, soit les mettre de la DB ou à partir du Web .config.

ou

2) utiliser une entité distincte pour maintenir les paramètres, peut-être un dictionnaire, soit l'utiliser directement ou ont-il un membre de la classe d'entrée

Ce qui frappe tout comme le plus facile/flexible? Ce qui m'inquiète, c'est que ça ne me semble pas très branché (si je veux ajouter plus de fonctionnalités) car changer les méthodes de classe d'une entité me ferait aussi changer l'application elle-même (ce qui ressemble à une violation d'OCP)). Le second a l'impression que c'est plus lourd, surtout si je dois ensuite lancer ou analyser des valeurs à partir d'un dictionnaire.

Répondre

7

Je dirais que le fait de savoir si une valeur est configurable ou non n'est pas pertinent du point de vue du modèle de domaine - ce qui importe est qu'il soit défini de manière externe.

Disons que vous avez une classe qui doit avoir un nom. Si le nom est toujours requis, il doit être encapsulé en tant qu'invariant quelle que soit la source de la valeur. Voici un exemple C#:

public class MyClass 
{ 
    private string name; 

    public MyClass(string name) 
    { 
     if(name == null) 
     { 
      throw new ArgumentNullException("name"); 
     } 

     this.name = name; 
    } 

    public string Name 
    { 
     get { return this.name; } 
     set 
     { 
      if(value == null) 
      { 
       throw new ArgumentNullException("name"); 
      } 
      this.name = value; 
     } 
    } 
} 

Une classe comme celui-ci protège efficacement l'invariant: Nom ne doit pas être nulle. Les modèles de domaine doivent encapsuler des invariants comme celui-ci sans tenir compte du consommateur qui les utilisera - sinon, ils n'atteindraient pas l'objectif de Supple Design.

Mais vous avez demandé à propos des valeurs par défaut. Si vous avez une bonne valeur par défaut pour Name, alors comment communiquez-vous cette valeur par défaut à MyClass.

C'est là que les usines sont utiles. Vous séparez simplement la construction de vos objets de leur implémentation. C'est souvent une bonne idée dans tous les cas. Il est moins important de choisir une implémentation de type Abstract Factory ou Builder, mais Abstract Factory est un bon choix par défaut.

Dans le cas de MyClass, on pourrait définir l'interface IMyClassFactory:

public interface IMyClassFactory 
{ 
    MyClass Create(); 
} 

Maintenant, vous pouvez définir une implémentation qui tire le nom d'un fichier de configuration:

public ConfigurationBasedMyClassFactory : IMyClassFactory 
{ 
    public MyClass Create() 
    { 
     var name = ConfigurationManager.AppSettings["MyName"]; 
     return new MyClass(name); 
    } 
} 

Assurez-vous que le code Cela nécessite que les instances de MyClass utilisent IMyClassFactory pour le créer au lieu de le créer manuellement.

+0

Les valeurs par défaut étaient un exemple, peut-être un mauvais; Je suis familier avec le modèle Factory. Un autre exemple devrait être quelque chose qui devrait s'appliquer à toutes les instances d'une classe, mais qui peut changer au niveau de l'application. Peut-être quelque chose comme le nombre d'instances à charger dans une liste (toujours) ou une règle sur l'affichage ou non des commentaires. Ceux-ci ne me frappent pas vraiment en tant que valeurs au niveau de l'instance, ou est-ce que je ne comprends pas quelque chose? – Paul

+1

Vous pouvez toujours encapsuler une ou plusieurs valeurs connexes dans un type, puis injecter une instance de ce type dans tous les consommateurs. Pour des raisons d'efficacité (ou pour toute autre raison), vous pouvez choisir d'injecter une seule instance partagée alors que les consommateurs n'ont aucune idée de la durée de vie de l'objet injecté. Cela gardera vos options ouvertes. –

Questions connexes