Considere este ejemplo:
Tengo un sitio web Permite a los usuarios hacer publicaciones (puede ser cualquier cosa) y agregar etiquetas que describen la publicación. En el código, tengo dos clases que representan la publicación y las etiquetas. Vamos a llamar a estas clases Post
y Tag
.
Post
se encarga de crear publicaciones, eliminar publicaciones, actualizar publicaciones, etc.
Tag
se encarga de crear etiquetas, eliminar etiquetas, actualizar etiquetas, etc.
Hay una operación que falta. La vinculación de etiquetas a publicaciones. Estoy luchando con quién debería hacer esta operación. Podría encajar igualmente bien en cualquier clase.
Por un lado, la Post
clase podría tener una función que tome a Tag
como parámetro y luego la almacene en una lista de etiquetas. Por otro lado, la Tag
clase podría tener una función que tome a Post
como parámetro y vincule Tag
a Post
.
Lo anterior es solo un ejemplo de mi problema. De hecho, me encuentro con esto con varias clases que son todas similares. Podría encajar igualmente bien en ambos. Además de poner realmente la funcionalidad en ambas clases, qué convenciones o estilos de diseño existen para ayudarme a resolver este problema. ¿Asumo que tiene que haber algo menos que elegir uno?
¿Quizás ponerlo en ambas clases es la respuesta correcta?
fuente
No, no en ambos! Debería estar en un solo lugar.
Lo que encuentro incómodo en su pregunta es el hecho de que usted dice "
Post
se encarga de crear publicaciones, eliminar publicaciones, actualizar publicaciones" y lo mismo paraTag
. Bueno, eso no está bien.Post
solo puede encargarse de actualizar, lo mismo paraTag
. Crear y eliminar es el trabajo de otra persona, externo aPost
yTag
(llamémosloStore
).La buena responsabilidad
Post
es "conoce a su autor, contenido y fecha de la última actualización". La buena responsabilidadTag
es "conoce su nombre y propósito (léase: descripción)". La buena responsabilidadStore
es "conoce todas las publicaciones y todas las etiquetas y puede agregarlas, eliminarlas y buscarlas".Si nos fijamos en estos tres participantes, ¿quién es, naturalmente, el que debería tener el conocimiento de la relación Post-Tag?
(para mí, es la publicación, parece natural que "conozca sus etiquetas"; la búsqueda inversa (todas las publicaciones para una etiqueta) parece ser el trabajo de la tienda; aunque puedo estar equivocado)
fuente
ConditionalWeakTable
(suponiendo que uno tenga la suerte de tener un marco donde exista)?Hay un detalle importante que falta en la ecuación. ¿Por qué la etiqueta contiene publicación y viceversa? La respuesta a esta pregunta determina la solución para cada conjunto dado.
En general, puedo pensar en una situación similar. Una caja y contenido. Una caja tiene contenido, por lo que una relación has-a es apropiada. ¿Los contenidos pueden tener una caja? Claro, una caja con una caja. Una caja es contenido. Pero IS-A no es un buen diseño para todas las cajas. En tal caso, consideraría el patrón decorador. De esta manera, una caja se decora con contenido en tiempo de ejecución según sea necesario.
Las etiquetas también pueden tener publicaciones, pero para mí esto no es una relación estática. Más bien podría ser un informe de todas las publicaciones que tienen dicha etiqueta. En este caso es una nueva entidad, no tiene-a.
fuente
Si bien, en teoría, cosas como esa pueden ir en cualquier dirección, en la práctica, cuando se llega a la implementación, una de ellas es casi siempre mejor que la otra. Mi presentimiento es que encajará mejor en la
Post
clase porque la asociación se creará durante la creación o edición de la publicación, cuando otras cosas sobre la publicación están cambiando al mismo tiempo.Además, si está asociando varias etiquetas y desea hacerlo en una actualización de la base de datos, deberá crear algún tipo de lista de todas las etiquetas asociadas con la misma publicación antes de realizar la actualización. Esa lista encaja mucho mejor en la
Post
clase.fuente
Personalmente, no agregaría esa funcionalidad a ninguno de ellos.
Para mí, tanto
Post
yTag
son objetos de datos, por lo que no se debe manejar la funcionalidad de base de datos. Simplemente deberían existir. Están destinados a almacenar datos y ser utilizados por otras partes de su aplicación.En cambio, tendría otra clase que es responsable de la lógica de su negocio y los datos relacionados con su página web. Si su página muestra una publicación y permite a los usuarios agregar etiquetas, entonces la clase tendría un
Post
objeto y contendría funcionalidad para agregarTags
a esoPost
. Si su página muestra etiquetas y permite a los usuarios agregar publicaciones a esas etiquetas, contendría unTag
objeto y tendría funcionalidad para agregarPosts
a esoTag
.Aunque solo soy yo. Si cree que debe manejar la funcionalidad de la base de datos en sus objetos de datos, entonces recomendaría la respuesta de pdr
fuente
Cuando leí esta pregunta, lo primero que me vino a la mente fue una relación de base de datos Many To Many . Las publicaciones pueden tener muchas etiquetas ... Las etiquetas pueden tener muchas publicaciones ... Me parece que ambas clases necesitan la capacidad de gestionar esta relación hasta cierto punto.
Desde el punto de vista de la publicación ...
Si edita o crea una publicación, una actividad secundaria se convierte en la gestión de las relaciones de etiquetas .
En mi opinión, la creación de un TAG completamente nuevo no pertenece aquí.
Desde el punto de vista de la etiqueta ...
Puede crear una etiqueta sin tener que asignarla a una publicación. La única actividad que veo que implica interactuar con una publicación es una función Eliminar etiqueta. Sin embargo, esta función debería ser una función independiente independiente.
Esto solo funcionará si hay una tabla de enlace de base de datos que resuelva la relación Muchos a Muchos
fuente