Question

Pour différentes raisons, nous écrivons une nouvelle bibliothèque de stockage d’objets d’entreprise / de données. L'une des exigences de cette couche est de séparer la logique des règles de gestion et de la couche de stockage de données réelle.

Il est possible que plusieurs couches de stockage de données implémentent l'accès au même objet, par exemple une base de données principale "Base de données". source de stockage de données qui implémente la plupart des objets et une autre " ldap " source qui implémente un objet utilisateur. Dans ce scénario, l'utilisateur peut éventuellement provenir d'une source LDAP, avec éventuellement des fonctionnalités légèrement différentes (par exemple, il n'est pas possible de sauvegarder / mettre à jour l'objet User), mais il est sinon utilisé de la même manière par l'application. Un autre type de stockage de données peut être un service Web ou une base de données externe.

Nous envisageons de mettre en œuvre cette stratégie de deux manières principales. Un collègue et moi-même ne sommes pas d’accord sur un point fondamental, ce qui est correct. Je voudrais des conseils sur lequel est le meilleur à utiliser. Je vais essayer de garder les descriptions de chacun de ces sujets aussi neutres que possible, car je recherche ici des points de vue objectifs.

  • Les objets métier sont des classes de base et les objets de stockage de données héritent des objets métier. Le code client concerne les objets de stockage de données.

    Dans ce cas, chaque objet de stockage de données hérite des règles de gestion courantes, et ce sont les objets de stockage de données directement utilisés par le code client.

    Cela implique que le code client détermine la méthode de stockage de données à utiliser pour un objet donné, car il doit déclarer explicitement une instance pour ce type d'objet. Le code client doit connaître explicitement les informations de connexion pour chaque type de stockage de données utilisé.

    Si une couche de stockage de données implémente des fonctionnalités différentes pour un objet donné, le code client le sait explicitement au moment de la compilation, car l’objet a un aspect différent. Si la méthode de stockage des données est modifiée, le code client doit être mis à jour.

  • Les objets métier encapsulent les objets de stockage de données.

    Dans ce cas, les objets métier sont directement utilisés par l'application cliente. L'application client transmet les informations de connexion de base à la couche métier. La décision concernant la méthode de stockage de données utilisée par un objet donné est prise par le code de l'objet métier. Les informations de connexion seraient un bloc de données provenant d'un fichier de configuration (l'application cliente ne connaît pas vraiment les détails de celui-ci), qui peut être une chaîne de connexion unique pour une base de données ou plusieurs chaînes de connexion pour différents types de stockage de données. Des types de connexion de stockage de données supplémentaires peuvent également être lus depuis un autre emplacement, par exemple une table de configuration dans une base de données qui spécifie les URL vers divers services Web.

    L'avantage ici est que, si une nouvelle méthode de stockage de données est ajoutée à un objet existant, un paramètre de configuration peut être défini au moment de l'exécution pour déterminer quelle méthode utiliser, et il est complètement transparent pour les applications client. Les applications client n'ont pas besoin d'être modifiées si la méthode de stockage des données d'un objet donné change.

  • Les objets métier sont des classes de base, des objets source de données hérités des objets métier. Le code client concerne principalement les classes de base.

    Ceci est similaire à la première méthode, mais le code client déclare les variables des types d'objet métier de base et les méthodes Load () / Create () / etc sur les objets métier renvoient les objets appropriés de type source de données.

    L'architecture de cette solution est similaire à celle de la première méthode, mais la différence principale réside dans le choix de l'objet de stockage de données à utiliser pour un objet métier donné qui est pris par la couche de gestion et non par le code client.

Je sais qu'il existe déjà des bibliothèques ORM offrant certaines de ces fonctionnalités, mais veuillez en tenir compte pour le moment (il est possible qu'une couche de stockage de données soit mise en œuvre avec l'une de ces bibliothèques ORM) - notez également que je suis délibérément ne vous dis pas quelle langue est utilisée ici, à part qu'elle soit fortement typée.

Je cherche ici un conseil général sur la méthode qu'il est préférable d'utiliser (ou n'hésitez pas à suggérer autre chose), et pourquoi.

Était-ce utile?

La solution

Puis-je suggérer une autre alternative, avec éventuellement un meilleur découplage: les objets métier utilisent des objets de données et les objets de données implémentent des objets de stockage. Cela doit conserver les règles métier dans les objets métier mais sans aucune dépendance de la source ou du format de stockage, tout en permettant aux objets de données de prendre en charge toutes les manipulations nécessaires, y compris la modification dynamique des objets de stockage (par exemple, pour la manipulation en ligne / hors ligne).

cela tombe dans la deuxième catégorie ci-dessus (les objets métier encapsulent les objets de stockage de données), mais sépare plus clairement la sémantique des données des mécanismes de stockage

Autres conseils

Vous pouvez également avoir une façade à garder de votre client pour appeler l’entreprise directement. En outre, cela crée des points d’entrée communs pour votre entreprise.

Comme indiqué précédemment, votre entreprise ne doit être exposée qu'à votre DTO et à votre façade.

Oui. Votre client peut traiter avec les DTO. C'est le moyen idéal pour transmettre des données via votre application.

Je préfère généralement que "l'objet métier encapsule un objet de données / un stockage". meilleur. Cependant, dans le court terme, vous pouvez trouver une redondance élevée avec vos objets de données et vos objets métier qui peut sembler inutile. Cela est particulièrement vrai si vous optez pour un ORM comme base de votre couche d'accès aux données (DAL). Mais, à long terme, le véritable avantage est le cycle de vie des applications. Comme illustré, il n’est pas rare que " data " provenir d'un ou de plusieurs sous-systèmes de stockage (non limités au SGBDR), en particulier avec l'avènement de l'informatique en nuage, et comme c'est généralement le cas dans les systèmes distribués. Par exemple, vous pouvez avoir certaines données provenant d'un service Restful, un autre fragment ou objet d'un SGBDR, un autre d'un fichier XML, LDAP, etc. Avec cette réalisation, cela implique l’importance d’une très bonne encapsulation de l’accès aux données de l’entreprise. Faites attention aux dépendances que vous exposez (DI) à travers vos propriétés et propriétés.

Cela étant dit, une approche à laquelle je me suis habitué consiste à mettre le "viande" de l'architecture dans un contrôleur de gestion. Considérant que l'accès aux données contemporain est davantage une ressource que la pensée traditionnelle, le contrôleur accepte alors un URI ou une autre forme de métadonnées pouvant être utilisée pour savoir quelles ressources de données il doit gérer pour les objets métier. Ensuite, les objets métier n'encapsulent pas eux-mêmes l'accès aux données; plutôt le contrôleur fait. Ceci maintient vos objets métier légers et spécifiques et permet à votre contrôleur de fournir une optimisation, une possibilité de composition, une ambiance de transaction, etc. Notez que votre contrôleur serait alors "hôte". vos collections d’objets d’entreprise, un peu comme le fait le contrôleur de nombreux ORM.

En outre, envisagez également la gestion des règles métier. Si vous pliez les yeux sur votre UML (ou le modèle que vous avez dans la tête, comme je le fais: D), vous remarquerez que votre modèle de règles métier est en réalité un autre modèle, parfois même persistant (si vous utilisez un moteur de règles métier, par exemple). . J'envisagerais de laisser également le contrôleur de gestion contrôler également votre sous-système de règles et laisser votre objet métier référencer les règles via le contrôleur. La raison en est que, inévitablement, les implémentations de règles doivent souvent effectuer des recherches et des contrôles croisés afin de déterminer la validité. Souvent, cela peut nécessiter des recherches d'objet métier hydratées, ainsi que des recherches de base de données back-end. Envisagez de détecter les entités en double, par exemple, où seul le " nouveau " l'un est hydraté. En laissant vos règles à la gestion de votre contrôleur métier, vous pouvez faire presque tout ce dont vous avez besoin sans pour autant sacrifier cette belle abstraction propre dans votre "modèle de domaine".

En pseudo-code:

using(MyConcreteBusinessContext ctx = new MyConcreteBusinessContext("datares://model1?DataSource=myserver;Catalog=mydatabase;Trusted_Connection=True ruleres://someruleresource?type=StaticRules&handler=My.Org.Business.Model.RuleManager")) {

User user = ctx.GetUserById("SZE543");
user.IsLogonActive = false;
ctx.Save();
}

//a business object
class User : BusinessBase {
  public User(BusinessContext ctx) : base(ctx) {}

  public bool Validate() {
    IValidator v = ctx.GetValidator(this);
    return v.Validate();
  }
}

// a validator
class UserValidator : BaseValidator, IValidator {
 User userInstance;
 public UserValidator(User user) {
  userInstance = user;
 }

 public bool Validate() {
   // actual validation code here
   return true;
 }
}

Les clients ne doivent jamais traiter directement avec des objets de stockage. Ils peuvent traiter directement avec les DTO, mais tout objet disposant d'une logique de stockage non encapsulée dans votre objet métier ne doit pas être appelé directement par le client.

Découvrez CSLA.net par Rocky Lhotka.

Eh bien, me voici, le collègue de travail Greg a mentionné.

Greg a décrit les alternatives que nous avons envisagées avec une grande précision. Je veux juste ajouter quelques considérations supplémentaires à la description de la situation.

Le code client peut ne pas connaître le stockage de données dans lequel les objets métier sont stockés, mais il est également possible qu’il n’existe qu’un seul stockage de données ou plusieurs stockages de données pour le même type d’objet d’entreprise (utilisateurs stockés dans la base de données locale et externe). LDAP), mais le client ne crée pas ces objets métier. En termes d’analyse système, cela signifie qu’il ne doit exister aucun cas d’utilisation dans lequel l’existence de deux datastorages d’objets du même type peut affecter le flux de cas d’utilisation.

Dès que le besoin de distinguer des objets créés dans différents stockages de données apparaîtra, le composant client doit prendre conscience de la multiplicité des stockages de données dans son univers, et il deviendra inévitablement responsable de la décision du stockage à utiliser. de création d’objet (et, je pense, de chargement d’objet à partir d’un stockage de données). La couche de gestion peut prétendre prendre cette décision, mais l'algorithme de prise de décision sera basé sur le type et le contenu des informations provenant du composant Client, ce qui rendra le client effectivement responsable de la décision.

Cette responsabilité peut être mise en œuvre de nombreuses manières: il peut s'agir d'un objet de connexion d'un type spécifique pour chaque stockage de données; il peut être séparé des méthodes pour appeler pour créer de nouvelles instances de BO, etc.

Cordialement,

Michael

CLSA existe depuis longtemps. Cependant, j'aime bien l'approche décrite dans le livre d'Eric Evans http://dddcommunity.org/

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top