Considere este exemplo:
Eu tenho um site. Ele permite que os usuários façam postagens (podem ser qualquer coisa) e adicionem tags que descrevam a postagem. No código, tenho duas classes que representam a postagem e as tags. Vamos chamar essas classes Post
e Tag
.
Post
cuida da criação de postagens, exclusão de postagens, atualização de postagens etc.
Tag
cuida da criação de tags, exclusão de tags, atualização de tags etc.
Há uma operação que está faltando. A vinculação de tags a postagens. Estou lutando com quem deve fazer esta operação. Poderia se encaixar igualmente bem em qualquer classe.
Por um lado, a Post
classe pode ter uma função que aceita a Tag
como parâmetro e, em seguida, armazena-a em uma lista de tags. Por outro lado, a Tag
classe pode ter uma função que usa a Post
como parâmetro e vincula o Tag
a Post
.
O acima é apenas um exemplo do meu problema. Na verdade, estou enfrentando isso com várias classes semelhantes. Poderia se encaixar igualmente bem em ambos. Além de realmente colocar a funcionalidade nas duas classes, quais convenções ou estilos de design existem para me ajudar a resolver esse problema. Estou assumindo que deve haver algo menos do que escolher um?
Talvez colocá-lo nas duas classes seja a resposta correta?
fonte
Não, não em ambos! Deve estar em um só lugar.
O que acho incômodo na sua pergunta é o fato de você dizer "
Post
cuida da criação de postagens, exclusão de postagens, atualização de postagens" e o mesmo paraTag
. Bem, isso não está certo.Post
só pode cuidar da atualização, o mesmo paraTag
. Criar e excluir é o trabalho de outra pessoa, externaPost
eTag
(vamos chamá-loStore
).A boa responsabilidade
Post
é "conhece seu autor, conteúdo e data da última atualização". A boa responsabilidadeTag
é "conhece seu nome e propósito (leia-se: descrição)". Uma boa responsabilidadeStore
é "conhecer todas as postagens e todas as tags e pode adicionar, remover e pesquisar".Se você olhar para esses três participantes, quem é naturalmente o que deve ter o conhecimento do relacionamento pós-tag?
(para mim, é o Post, parece natural que "conheça suas tags"; a pesquisa reversa (todas as postagens de uma tag) parece ser o trabalho da loja; embora eu possa estar enganado)
fonte
ConditionalWeakTable
(assumindo que alguém tenha a sorte de ter uma estrutura onde existe)?Falta um detalhe importante na equação. Por que a tag contém post e vice-versa? A resposta a esta pergunta determina a solução para cada conjunto fornecido.
Em geral, posso pensar em uma situação semelhante. Uma caixa e conteúdo. Uma caixa tem conteúdo, portanto, um relacionamento tem um é apropriado. O conteúdo pode ter uma caixa? Claro, uma caixa com uma caixa. Uma caixa é o conteúdo. Mas o IS-A não é um bom design para todas as caixas. Nesse caso, eu consideraria o padrão decorador. Dessa forma, uma caixa é decorada com o conteúdo em tempo de execução, conforme necessário.
As tags também podem ter Postagens, mas para mim isso não é um relacionamento estático. Em vez disso, poderia ser um relatório de todas as postagens com a referida tag. Nesse caso, é uma nova entidade, não possui-a.
fonte
Enquanto na teoria coisas assim podem ser aplicadas de qualquer maneira, na prática, quando você se dedica à implementação, uma maneira é quase sempre melhor do que a outra. Meu palpite é que ele se encaixará melhor na
Post
classe porque a associação será criada durante a criação ou edição da postagem, quando outras coisas sobre a postagem estiverem mudando ao mesmo tempo.Além disso, se você estiver associando várias tags e quiser fazer isso em uma atualização do banco de dados, precisará criar algum tipo de lista de todas as tags associadas à mesma postagem antes de fazer a atualização. Essa lista se encaixa muito melhor na
Post
classe.fonte
Pessoalmente, eu não adicionaria essa funcionalidade a nenhum deles.
Para mim, ambos
Post
eTag
são objetos de dados, não deve lidar com a funcionalidade do banco de dados. Eles deveriam simplesmente existir. Eles foram criados para armazenar dados e serem usados por outras partes do seu aplicativo.Em vez disso, eu teria outra classe responsável por sua lógica de negócios e dados pertencentes à sua página da web. Se sua página estiver exibindo uma postagem e permitindo que os usuários adicionem tags, a classe terá um
Post
objeto e conterá funcionalidade para adicionarTags
a elaPost
. Se sua página estiver exibindo tags e permitindo que os usuários adicionem postagens a essas tags, ela conteria umTag
objeto e teria funcionalidade para adicionarPosts
a elaTag
.Mas sou apenas eu. Se você acha que precisa lidar com a funcionalidade do banco de dados em seus objetos de dados, recomendo a resposta do pdr
fonte
Ao ler esta pergunta, a primeira coisa que me veio à mente foi um relacionamento de banco de dados Muitos para Muitos . As postagens podem ter muitas tags ... As tags podem ter muitas postagens .... Parece-me que as duas classes precisam da capacidade de gerenciar esse relacionamento até certo ponto.
Do ponto de vista da publicação ...
Se você editar ou criar uma publicação, uma atividade secundária passará a gerenciar os relacionamentos de tags .
Na IMO, a criação de um TAG completamente novo não pertence aqui.
Do ponto de vista do Tag ...
Você pode criar um Tag sem precisar atribuí-lo a uma Postagem. A única atividade que vejo que envolve a interação com uma publicação é uma função Excluir marca. No entanto, essa função deve ser uma função independente independente.
Isso funcionará apenas se houver uma tabela de vinculação de banco de dados que resolva o relacionamento Muitos para Muitos
fonte