8
votes

Utiliser le "principe de responsabilité unique" oblige mes conteneurs à avoir des ensembles publics

J'essaie du mal à concevoir à la suite des principes solides. Ce que j'ai trouvé, c'est que lorsque vous utilisez le "principe de responsabilité unique" (le s de solide), vous devez généralement diviser les classes entre les conteneurs de données et les processeurs de données. Par exemple, si j'ai une personne de classe avec 5 propriétés lues de la DB au lieu de mettre tout à l'intérieur d'une classe, je crée une classe de personne avec les propriétés et une autre classe Direader qui lit ces informations de la base de données et crée la personne.

Si je fais que je dois ouvrir les propriétés de la personne afin que la personnière pourrait y accéder, mais j'ai moins d'encapsulation que de mettre tout dans une boîte noire et de rendre les propriétés lisibles.

Est-ce que je manque quelque chose ou est-ce un inconvénient de ce principe?

Merci d'avance

EDIT: J'ai changé l'écrivain de la personne en un lecteur de personne car il n'était pas nécessaire de faire du public des immeubles au début.


1 commentaires

Le Mentalo Le modèle de conception est une solution classique à la sérialisation / désérialisation sans violation d'encapsulation. Cela étant dit, les outils modernes utilisent simplement une réflexion.


4 Réponses :


3
votes

La plupart des stratégies d'accès aux données (techniques ORM) impliquent des compromis du type que vous décrivez. Les moins intrusifs utilisent la réflexion (ou l'introspection, etc.) pour renseigner vos entités lorsqu'ils doivent (lorsqu'il n'y a pas d'entretteurs publics, par exemple).

Ayant dit que, si vos entités ne sont que des conteneurs de données (comme dans le modèle de domaine anémique ), le principe de responsabilité unique ne devrait pas vraiment vous inquiéter, car vos objets n'ont pas une logique complexe qui serait gâtée par (ou interférer avec) le code d'accès aux données.


2 commentaires

Merci Jeff mais je ne pense pas que ce soit un modèle de domaine anémique car je ne divise pas la logique commerciale du modèle de domaine, je sors de la persistance du modèle de domaine. Tout ce que j'ai lu me prend dans ce chemin, il suffit de lire l'exemple ici p2p.wrox.com/content/articles/...


@Somos - Désolé, je voulais avoir l'impression que vous fractionnez déjà la logique commerciale du modèle de domaine (puisque vous avez décrit les objets comme de simples conteneurs). Si c'était le cas, je ne serais pas trop difficile du SRP. Comme ce n'est pas le cas, c'est une préoccupation juste.



0
votes

Vous pensez trop granulièrement. Une classe spécifique devrait lire la base de données, mais vous n'avez pas besoin d'une classe dont le seul travail est de créer une personne. C'est juste gaspillé. Un seul lecteur de base de données devrait être capable de créer une classe qui traverse la base de données, car c'est son travail. À lire dans la base de données.

Il n'y a pas de problèmes d'encapsulation avec les propriétés de la personne d'ouverture afin que Databaseereader puisse y accéder, car la personne est redondante si aucune classe n'est capable de la créer. C'est une partie inhérente de toutes les classes responsables d'être créées et destructibles.


3 commentaires

L'ouverture d'une classe permet aux autres de modifier ses données lorsqu'elles ne sont pas supposées de le faire (pire encore lorsqu'elles sont des classes publiques pouvant être utilisées par des personnes tierces qui ne savent pas qu'ils ont une propriété publique qu'ils ne devraient pas utiliser ce.


Quoi qu'il en soit, je suis désolé mais votre réponse n'a rien à voir avec ma question. Je pourrais accepter qu'un lecteur pourrait tout lire, le problème est toujours là, vous avez des setteurs publics lorsque vous n'auriez que getters si le lecteur était à l'intérieur de la classe de la personne.


@Somos: La plupart des langues fournissent un contrôle plus fin. En C ++, vous pouvez "ami" des classes et en C #, vous pouvez faire des propriétés internes et avoir des cours imbriquées. Je pense que Java peut avoir un équivalent aussi. Public, protégé, privé ne sont pas les seuls contrôles d'accès.



1
votes

Je suis certainement d'accord avec vous que parfois vous rencontrez ce problème. Je l'ai expérimenté avec sérialisement, qui est similaire à orm. Dans mon cas, j'avais besoin d'écrire l'état d'un objet à un fichier (binaire).

Dans certains cas, il peut être approprié de créer une interface à travers laquelle l'état interne peut être écrit et lu. Donc, votre classe de personne obtiendrait deux méthodes "Enregistrer" et "Charger" (ou "Write" et "Lire" ou tout ce que vous pensez être approprié). Ces méthodes sont transmises respectivement un "ipropertywriter" et "ipropertyeader". (Dans mon cas, je les ai appelés instruits instruits et tante). P>

personne :: Save (Writer IPropertyWriter) ferait alors P>

writer.writeProperty("name", this.name);
writer.writeProperty("age", this.age);


1 commentaires

MMMM, c'est un peu complexe mais de toute façon une solution de travail. Je vais définitivement essayer dans mon code. Merci!



3
votes

Peut-être que je manque quelque chose, mais pourquoi n'écrirez-vous pas de constructeur pour la classe de personne qui accepte toutes ses propriétés? De cette façon, la personneReader sera en mesure de créer une personne sans que vous ouvriez les propriétés de la personne.

Une autre option consiste à marquer la sécheuse des propriétés de la personne en tant que interne (et rendez les internes de l'assemblage visibles à l'assemblage de la donnée, si c'est dans un assemblage différent). Cela vous permettra d'accéder aux propriétés de la personne, mais empêchera toute personne de les changer en dehors de l'assembly.


1 commentaires

Vous avez raison, mais c'était un exemple simple, la situation réelle concerne les objets avec certains attributs qui ne peuvent pas savoir au moment de la construction.