Considérez cet exemple:
J'ai un site Web. Il permet aux utilisateurs de créer des messages (peut être n'importe quoi) et d'ajouter des balises qui décrivent le message. Dans le code, j'ai deux classes qui représentent le message et les balises. Appelons ces classes Post
et Tag
.
Post
s'occupe de créer des posts, de supprimer des posts, de mettre à jour des posts, etc.
Tag
s'occupe de créer des tags, de supprimer des tags, de mettre à jour des tags, etc.
Il manque une opération. La liaison des balises aux messages. Je me bats avec qui devrait faire cette opération. Il pourrait tout aussi bien s'intégrer dans l'une ou l'autre classe.
D'une part, la Post
classe pourrait avoir une fonction qui prend a Tag
comme paramètre, puis la stocke dans une liste de balises. D'un autre côté, la Tag
classe pourrait avoir une fonction qui prend un Post
comme paramètre et lie le Tag
au Post
.
Ce qui précède n'est qu'un exemple de mon problème. En fait, je rencontre cela avec plusieurs classes qui sont toutes similaires. Il pourrait tout aussi bien convenir aux deux. À moins de mettre la fonctionnalité dans les deux classes, quelles conventions ou quels styles de conception existent pour m'aider à résoudre ce problème. Je suppose qu'il doit y avoir autre chose que d'en choisir un?
Peut-être que le mettre dans les deux classes est la bonne réponse?
la source
Non, pas dans les deux! Il devrait être au même endroit.
Ce que je trouve inquiétant dans votre question, c'est le fait que vous dites "
Post
s'occupe de créer des messages, de supprimer des messages, de mettre à jour des messages" et de même pourTag
. Eh bien, ce n'est pas vrai.Post
ne peut que s'occuper de la mise à jour, de même pourTag
. La création et la suppression sont le travail de quelqu'un d'autre, extérieur àPost
etTag
(appelons-le simplementStore
).Une bonne responsabilité pour
Post
"connaît son auteur, son contenu et la date de la dernière mise à jour". Une bonne responsabilitéTag
est "connaît son nom et son but (lire: description)". Une bonne responsabilité pourStore
"connaît tous les messages et toutes les balises et peut les ajouter, les supprimer et les rechercher".Si vous regardez ces trois participants, qui est le plus naturellement celui qui devrait avoir la connaissance de la relation Post-Tag?
(pour moi, c'est le Post, il semble naturel qu'il "connaisse ses tags"; la recherche inversée (tous les posts pour un tag) semble être le travail du Store; même si je me trompe)
la source
ConditionalWeakTable
(en supposant que l'on a la chance d'avoir un cadre là où il en existe un)?Il y a un détail important manquant dans l'équation. Pourquoi le tag contient-il du courrier et vice-versa? La réponse à cette question détermine la solution pour chaque ensemble donné.
En général, je peux penser à une situation similaire. Une boîte et son contenu. Une boîte a du contenu, donc une relation has-a est appropriée. Le contenu peut-il avoir une boîte? Bien sûr, une boîte avec une boîte. Une boîte est le contenu. Mais IS-A n'est pas une bonne conception pour toutes les boîtes. Dans un tel cas, je considérerais le motif de décorateur. De cette façon, une boîte est décorée avec du contenu lors de l'exécution si nécessaire.
Les tags peuvent également avoir des messages, mais pour moi, ce n'est pas une relation statique. Il pourrait plutôt s'agir d'un rapport de tous les messages ayant ladite balise. Dans ce cas, c'est une nouvelle entité, pas has-a.
la source
Alors qu'en théorie, des choses comme ça peuvent aller dans les deux sens, dans la pratique, lorsque vous passez à la mise en œuvre, une façon est presque toujours mieux adaptée que l'autre. Mon intuition est qu'elle s'intégrera mieux dans la
Post
classe car l'association sera créée lors de la création ou de la modification du post, lorsque d'autres choses sur le post changent en même temps.En outre, si vous associez plusieurs balises et souhaitez le faire dans une mise à jour de base de données, vous devez créer une sorte de liste de toutes les balises associées à la même publication avant de procéder à la mise à jour. Cette liste s'intègre beaucoup mieux dans la
Post
classe.la source
Personnellement, je n'ajouterais cette fonctionnalité à aucun d'eux.
Pour moi, les deux
Post
etTag
sont des objets de données, donc ne devraient pas gérer la fonctionnalité de base de données. Ils devraient simplement exister. Ils sont destinés à contenir des données et à être utilisés par d'autres parties de votre application.Au lieu de cela, j'aurais une autre classe qui est responsable de votre logique métier et des données relatives à votre page Web. Si votre page affiche une publication et autorise les utilisateurs à ajouter des balises, la classe aurait un
Post
objet et contiendrait des fonctionnalités à ajouterTags
à celaPost
. Si votre page affiche des balises et permet aux utilisateurs d'ajouter des publications à ces balises, elle contiendrait unTag
objet et aurait des fonctionnalités à ajouterPosts
à celaTag
.C'est juste moi cependant. Si vous pensez que vous devez gérer la fonctionnalité de base de données dans vos objets de données, alors je recommanderais la réponse de pdr
la source
En lisant cette question, la première chose qui m'est venue à l'esprit était une relation de base de données plusieurs à plusieurs . Les publications peuvent avoir plusieurs balises ... Les balises peuvent avoir plusieurs publications .... Il me semble que les deux classes doivent avoir la capacité de gérer cette relation dans une certaine mesure.
Du point de vue de
la publication ... Si vous modifiez ou créez une publication, une activité secondaire devient la gestion des relations avec les balises .
OMI, la création d'un tout nouveau TAG n'a pas sa place ici.
Du point de vue du Tag ...
Vous pouvez créer un Tag sans avoir à l'assigner à un Post. La seule activité que je vois qui implique d'interagir avec un message est une fonction Supprimer le tag. Cependant, cette fonction devrait être une fonction autonome indépendante.
Cela ne fonctionnera que s'il existe une table de liaison de base de données qui résout la relation plusieurs à plusieurs
la source