2009-11-23 16 views
13

Volevo solo far riflettere i gruppi su come gestire i dettagli di configurazione delle entità.Impostazioni a livello di app in DDD?

Quello che sto pensando in particolare sono le impostazioni di alto livello che potrebbero essere modificate dall'amministratore. il tipo di cosa che potresti archiviare nell'app o web.config in definitiva, ma dalla prospettiva DDD dovrebbe essere impostato in qualche punto degli oggetti in modo esplicito.

Per ragioni, prendiamo come esempio un CMS basato sul Web o un'app blog.

una data entità blog voce ha un numero qualsiasi di impostazioni dell'istanza come Autore, Contento, ecc

Ma si potrebbe anche voler impostare (per esempio) di default Descrizione o Le parole chiave che tutte le voci del sito dovrebbe iniziare con se non sono cambiati dall'autore. Certo, potresti semplicemente inserire quelle costanti nella classe, ma il proprietario del sito non può modificare le impostazioni predefinite.

Così i miei pensieri sono i seguenti:

1) utilizzare la classe di livello (statici) di immobili da rappresentare quelle impostazioni, e quindi impostare quando l'applicazione si avvia, sia impostandole dal DB o dal web .config.

o

2) utilizzare un'entità separata per lo svolgimento delle impostazioni, eventualmente, un dizionario, o utilizzarlo direttamente o abbiano in essere un membro della classe Entry

Quello che tutto colpisce come il più facile/flessibile? La mia preoccupazione per la prima è che non mi sembra molto inseribile (se finisco per voler aggiungere più funzionalità) poiché cambiare i metodi di classe di un'entità mi farebbe cambiare anche l'app stessa (che sembra una violazione dell'OCP). Il secondo sembra più pesante, soprattutto se poi devo gettare o analizzare i valori da un dizionario.

risposta

7

Direi che se un valore è configurabile o meno è irrilevante dal punto di vista del modello di dominio - ciò che importa è che è definito esternamente.

Supponiamo che tu abbia una classe che deve avere un nome. Se il nome è sempre richiesto, deve essere incapsulato come invariante indipendentemente dall'origine del valore. Ecco un esempio 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; 
     } 
    } 
} 

Una classe come questa protegge efficacemente l'invariante: il nome non deve essere nullo. I modelli di dominio devono incapsulare invarianti come questo senza alcun riguardo a cui il consumatore li utilizzerà, altrimenti non raggiungerebbero l'obiettivo di Supple Design.

Ma si è chiesto dei valori di default. Se si dispone di un valore predefinito valido per Nome, come si comunica tale valore predefinito a MyClass.

Questo è dove le fabbriche sono utili. Separa semplicemente la costruzione dei tuoi oggetti dalla loro implementazione. Questa è spesso una buona idea in ogni caso. Se si sceglie un'implementazione di Abstract Factory o Builder è meno importante, ma Abstract Factory è una buona scelta predefinita.

Nel caso di MyClass, potremmo definire l'interfaccia IMyClassFactory:

public interface IMyClassFactory 
{ 
    MyClass Create(); 
} 

Ora è possibile definire un'implementazione che tira il nome da un file di configurazione:

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

Assicurarsi che il codice che ha bisogno di istanze di MyClass usa IMyClassFactory per crearlo invece di aggiornarlo manualmente.

+0

I valori predefiniti erano un esempio, forse uno scarso; Conosco il modello Factory. Un altro esempio potrebbe essere qualcosa che dovrebbe applicarsi a tutte le istanze di una classe, ma che può cambiare a livello di app. Forse qualcosa come il numero di istanze da caricare in un elenco (sempre) o una regola sull'opportunità o meno di mostrare i commenti. Questi non mi colpiscono davvero come valori a livello di istanza, o sto fraintendendo qualcosa? – Paul

+1

È sempre possibile incapsulare uno o più valori correlati in un tipo e quindi iniettare un'istanza di quel tipo in tutti i consumatori. Per motivi di efficienza (o qualsiasi altra ragione) puoi scegliere di iniettare una singola istanza condivisa mentre i consumatori non hanno idea della durata dell'oggetto iniettato. Ciò manterrà le tue opzioni aperte. –

Problemi correlati