2009-11-23 3 views
13

Ich wollte nur die Gruppen Gedanken über den Umgang mit Konfigurationsdetails von Entitäten bekommen.Einstellungen auf App-Ebene in DDD?

Was ich speziell denke, ist High-Level-Einstellungen, die admin-geändert werden können. die Art von Dingen, die Sie letztlich in der App oder web.config speichern, aber von der DDD-Perspektive sollte irgendwo in den Objekten explizit festgelegt werden.

Als Argumentation nehmen wir als Beispiel eine webbasierte CMS- oder Blog-App.

Eine bestimmte Blog-Eintrag Entität hat eine beliebige Anzahl von Instanzeinstellungen wie Autor, Inhalt, usw.

Aber Sie könnten auch (zum Beispiel) Standard Beschreibung oder Schlüsselwörter festlegen möchten, dass alle Einträge in der Website beginnen sollte mit wenn sie nicht vom Autor geändert werden. Sicher, Sie könnten nur diese Konstanten in der Klasse erstellen, aber der Websitebesitzer konnte die Standardwerte nicht ändern.

So sind meine Gedanken wie folgt:

1) verwenden Klasse-Ebene (statisch) Eigenschaften, diese Einstellungen repräsentieren, und sie dann festgelegt, wenn die App startet, können sie bei der Deutschen Bahn oder von der Web-Einstellung .config.

oder

2) verwenden, um eine separate Einheit für die Einstellungen zu halten, möglicherweise ein Wörterbuch, entweder direkt verwenden oder ein Mitglied der Eintragsklasse seiner

Was Sie alle als die leicht schlägt/flexibel? Meine Bedenken über die erste ist, dass es mich nicht als sehr einbaufähig empfindet (wenn ich am Ende mehr Funktionen hinzufügen möchte), da ich die App durch die Änderung der Klassenmethoden einer Entität ändern würde (was sich wie eine OCP-Verletzung anfühlt)). Der zweite fühlt sich jedoch schwerer an, besonders wenn ich dann Werte aus einem Wörterbuch werfen oder analysieren muss.

Antwort

7

Ich würde sagen, dass, egal ob ein Wert konfigurierbar ist oder nicht, aus der Perspektive des Domänenmodells irrelevant ist - was zählt ist, dass es extern definiert ist.

Angenommen, Sie haben eine Klasse, die einen Namen haben muss. Wenn der Name immer benötigt wird, muss er unabhängig von der Quelle des Werts als Invariante eingekapselt werden. Hier ist ein C# -Beispiel:

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

Eine Klasse wie diese schützt effektiv die Invariante: Name darf nicht null sein. Domänenmodelle müssen Invarianten wie diese kapseln, ohne Rücksicht darauf zu nehmen, welcher Verbraucher sie verwenden wird - andernfalls würden sie das Ziel von Geschmeidigem Design nicht erreichen.

Aber Sie fragte nach Standardwerten. Wenn Sie für Name einen guten Standardwert haben, wie kommunizieren Sie diesen Standardwert an MyClass.

Hier kommen Fabriken zum Einsatz. Sie trennen einfach die Konstruktion Ihrer Objekte von ihrer Implementierung. Dies ist in jedem Fall eine gute Idee. Ob Sie eine Abstract Factory- oder Builder-Implementierung wählen, ist weniger wichtig, aber Abstract Factory ist eine gute Standardauswahl.

Im Falle von MyClass, könnten wir die IMyClassFactory Schnittstelle definieren:

public interface IMyClassFactory 
{ 
    MyClass Create(); 
} 

Jetzt können Sie eine Implementierung definieren, die den Namen aus einer Konfigurationsdatei zieht:

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

Vergewissern Sie sich, dass Code Wenn Instanzen von MyClass benötigt werden, verwenden Sie IMyClassFactory, um sie zu erstellen, anstatt sie manuell neu zu erstellen.

+0

Standardwerte waren ein Beispiel, vielleicht ein schlechter; Ich kenne das Factory-Muster. Ein anderes Beispiel wäre etwas, das für alle Instanzen einer Klasse gelten sollte, sich aber auf der App-Ebene ändern kann. Vielleicht etwas wie die Anzahl der Instanzen, die in eine Liste geladen werden (immer) oder eine Regel darüber, ob Kommentare angezeigt werden oder nicht. Diese treffen mich nicht wirklich als Werte auf Instanzebene, oder verstehe ich etwas falsch? – Paul

+1

Sie könnten immer einen oder mehrere verwandte Werte in einen Typ einkapseln und dann eine Instanz dieses Typs in alle Consumers einfügen. Aus Gründen der Effizienz (oder aus anderen Gründen) können Sie eine einzelne, gemeinsam genutzte Instanz injizieren, während die Konsumenten keine Vorstellung von der Lebensdauer des injizierten Objekts haben. Das hält deine Optionen offen. –