Conception de la couche d'accès aux données en DDD

Excusez-moi pour mon pauvre anglais.

Ok, je pense à l'approche DDD maintenant et ça sonne bien mais... Il y a une petite question à ce sujet. DDD dit que la couche domain model est totalement découplée de la couche data access (et de toutes les autres couches). Ainsi, lorsque le DAL enregistrera un objet d'affaires, il n'aura accès qu'aux propriétés publiques de cet objet. Maintenant la question:

Comment pouvons-nous garantir (en général) qu'un ensemble de données publiques d'un objet est tout que nous avons besoin de restaurer l'objet plus tard?

exemple

nous avons les règles commerciales suivantes:

  1. L'Utilisateur et le domaine doivent être fournis pour l'objet d'affaires sur create.
  2. d'Utilisateur et de domaine ne peut pas être modifié après la création de l'objet.
  3. l'objet d'affaires ont la propriété de courrier électronique qui regarde comme "utilisateur@domaine".

voici un POCO pur qui décrit ces règles:

public class BusinessObject
{
    private string _user;
    private string _domain;

    public BusinessObject(string user, string domain)
    {
        _user = user;
        _domain = domain;
    }

    public string Email
    {
        get { return _user + "@" + _domain; }
    }
}

ainsi, à un moment donné, le DAL enregistrera cet objet dans le stockage externe (C'est-à-dire la base de données SQL). Évidemment, le DAL sauvegardera la propriété "Email" dans le champ associé dans la base de données. Tout ira très bien jusqu'au moment où nous demanderons au DAL de restaurer l'objet. Comment le DAL peut faire ça? L'objet doit avoir un setter public pour le Le champ "Email" au moins. Quelque chose comme

public string Email
{
    set
    {
        string[] s = value.Split("@");
        _user = s[0];
        _domain = s[1];
    }
}

en fait, l'objet aura des getters/setters publics pour les champs" User "et" Domain " et la méthode GetEmail(). Mais arrêter. Je ne veux pas que mon POCO ait une telle fonctionnalité! Il n'y a pas de règles métier. Ceci doit être fait pour la possibilité de sauvegarder/restaurer l'objet uniquement.

je vois une autre option. L'ORM qui fait partie du DAL pourrait être appelé à stocker tous les champs privés nécessaires pour restaurer l'objet. Mais c'est impossible si nous voulons garder le modèle de domaine séparé du DAL. La DAL ne peut pas compter sur certains membres privés de l'objet commercial.

la seule solution que je peux voir est d'avoir un instrument au niveau du système qui peut créer le dump de l'objet pour nous et peut restaurer l'objet à partir de ce dump à tout moment. Et le DAL doit mettre cette image pour le stockage en plus des propriétés publiques de l'objet. Donc quand le DAL doit restaurer le objet de stockage, il va utiliser le vidage pour cela. Et les propriétés publiques sauvegardées dans le stockage peuvent être utilisées lorsque le DAL exécute des opérations qui n'ont pas besoin que l'objet soit instancié (c'est-à-dire la plupart des requêtes link2sql).

est-ce que je le fais mal? Ai-je besoin d'en lire plus? À propos de certains modèles, ORM's peut-être?

4
demandé sur akakey 2011-09-09 21:32:30

2 réponses

je pense que vous avez mal compris cette partie:

je vois une autre option. L'ORM qui fait partie du DAL pourrait être demandé de stocker tous les champs privés nécessaires pour restaurer l'objet. Mais c'est impossible, si nous voulons garder le modèle de domaine séparés à partir de la DAL. La DAL ne peut pas compter sur certains membres privés de la objet de l'entreprise.

Le modèle de domaine

ne dépend pas de DAL. Son dans l'autre sens, DAL dépend du modèle de domaine. ORM a une connaissance intime des objets de domaine, y compris les champs privés. Il n'y a absolument rien de mal à cela. En fait, c'est la meilleure façon de mettre en œuvre l'ignorance persistante en DDD. Voici à quoi ressemble la classe Domain. Notez que

  • champs peuvent être privés et readonly
  • Constructeur public est utilisé uniquement par le code de client, pas par le DAL.
  • pas besoin pour bien des getters et setters
  • Business object est presque de 100% ignorants de la persistance des problèmes

La seule chose que DAL/ORM besoins est privé sans paramètre consturctor:

public class BusinessObject {
    private readonly string _user;
    private readonly string _domain;

    private BusinessObject(){}

    public BusinessObject(string user, string domain) {
        _user = user;
        _domain = domain;
    }

    public string Email {
        get { return _user + "@" + _domain; }
    }
}

et la magie se produit à ORM. Hibernate peut restaurer cet objet à partir de la base de données en utilisant ce fichier de cartographie:

<class name="BusinessObject" table="BusinessObjects">
    ...
    <property name="_user" column="User" />
    <property name="_domain" column="Domain" />
    ...
</class>

un autre aspect de la persistance-code de domaine ignorant est DDD Dépôt :

Définition: Un dépôt est un mécanisme pour encapsuler le stockage, la récupération et le comportement de recherche qui émule une collection d'objets.

L'interface du dépôt appartient au domaine et doit être basée sur langage ubiquitaire autant que possible. L'implémentation du dépôt appartient en revanche à DAL ( Principe D'Inversion de dépendance ).

5
répondu Dmitry 2011-09-09 18:43:28
public class BusinessObject
{
    private string _user;
    private string _domain;

   public BusinessObject(string email)
   {
      string[] s = value.Split("@");
      _user = s[0];
      _domain = s[1];    
   } 

   public BusinessObject(string user, string domain)
    {
        _user = user;
        _domain = domain;
    }

    public string Email
    {
        get { return _user + "@" + _domain; }
    }
}

une solution simple est de simplement avoir votre appel DAL new BusinessObject (email)

1
répondu Todd Smith 2011-09-09 18:15:08