Devo recuperar entidades relacionadas da entidade pai ou da camada de serviço?

5

Digamos que eu tenha uma estrutura de aplicativo de três camadas, com camadas de apresentação, serviço e dados. A camada de dados é gerenciada por um ORM e tem dois modelos / entidades, Show e Episode , com um relacionamento um-para-muitos (um show consiste em vários episódios).

Na camada de serviço, há um ShowService , que pode gerenciar shows. O aplicativo freqüentemente precisará exibir apenas episódios em que o tempo de publicação está no passado (ou seja, que são publicados).

Agora para a pergunta - onde devo colocar lógica para recuperar os episódios?

Acho que faz sentido ter um método getPublishedEpisodes() no Show model / entity, porque os episódios são, em essência, as partes que compõem um show. O ORM que estou usando (RedBeanPHP) tornaria muito fácil implementar algo assim no modelo Show :

public function getPublishedEpisodes(){
    $allEpisodes = $this->ownEpisodeList;
    return filterPublished($allEpisodes);
}

Agora posso apenas ligar

$episodes = $show->getPublishedEpisodes();

e tudo que eu preciso é de um Show para conseguir seus episódios publicados.

A outra opção seria colocar o método no ShowService , que de alguma forma não parece natural, mas tenho a sensação de que essa é a maneira "correta" de fazê-lo. Eu estou pensando que teria que fazer algo assim no ShowService :

public function getPublishedEpisodes(Show $show){
    $allEpisodes = $show->ownEpisodeList;
    return filterPublished($allEpisodes);
}

Mas sempre precisarei obter o ShowService sempre que quiser publicar episódios. Com a outra abordagem, posso passar os objetos Show por todo o lugar e apenas chamar $show->getPublishedEpisodes() quando quiser.

A primeira opção, que parece muito mais fácil - pelo menos a curto prazo, me dá problemas que não consigo ver agora?

    
por Magnus W 02.02.2017 / 17:57
fonte

1 resposta

0

Esta é uma pergunta difícil de responder, como muitos apontaram nos comentários, mas eu acho que vou pesar.

Meu primeiro pensamento é fazer o que é melhor para sua aplicação. Podemos nos aprofundar na teoria de DDD e afins, onde eu poderia ter uma opinião diferente (e eu, se você carrega comigo).

Se fizer mais sentido para você simplesmente carregar um show através do seu ORM e chamar algum método como getPublishedEpisodes() do que fazê-lo! Se você assinar uma abordagem ágil ou refatorar com frequência, poderá alterá-la posteriormente. É possível (e provavelmente) que sua primeira tentativa de um padrão ou arquitetura esteja errada ... Às vezes, simplesmente não sabemos o que precisamos até que tentemos.

Se você ORM não é intrusivo e não impõe uma dependência direta na classe Show , então provavelmente você está bem para seguir esse caminho. Programação Orientada a Aspectos é algo que você pode querer analisar e funciona bem com suas ideias. Pode não ser possível em PHP ou com o seu ORM, no entanto.

De qualquer forma, acho mais limpo usar seus modelos para encapsular a lógica de negócios e, nesse sentido, imagino que seu Episodes seria filho do Show . Se assim for, provavelmente teria um ShowRepository para carregar o Show , em que o repositório é uma dependência do ShowService . O ShowService gerenciaria a vinculação de suas entidades e lidaria com a coordenação da lógica de negócios.

Na minha versão deste aplicativo, apenas a partir de uma exibição de 1000 pés, quando eu carreguei o Show eu praticamente sempre carrego todo o Episodes com ele. Quando precisei obter apenas o Episodes para uma determinada visualização, posso usar alguma forma de Objeto de consulta para executar uma consulta mais personalizada. A única razão pela qual eu faria isso, no entanto, é se meu aplicativo estivesse realmente com desempenho ruim usando a ideia original de apenas buscar o Show com o Episodes anexado.

Usar a ideia do Objeto de consulta leva ao CQRS , que é um tópico bastante avançado e pode até não valer a pena sua aplicação.

Para reiterar, faça o que parece mais fácil de entender e manter para você e sua equipe. Só podemos dar tantos conselhos na internet, especialmente sem ver e entender o aplicativo e seu domínio.

Dito isto - e eu tomaria o resto disto com um grão de sal - se eu estivesse a escrever esta aplicação, preferiria uma abordagem diferente, provavelmente mais próxima da ideia da sua ShowService .

Quando você diz "entidade", penso em DDD. Isso pode ou não ser exato. Muitos ORM Providers chamam seus modelos de "entidades" - ahem Entity Framework ahem - que é uma espécie de erro. As Entidades do Entity Framework são realmente apenas Objetos de Transferência de Dados . Na minha opinião, "entidades" são entidades relacionadas ao Design Dirigido por Domínio. Entidades, como visto aqui, são definidas por sua identidade . Eles são os principais modelos que representam os conceitos estrategicamente importantes de um domínio ou negócio.

Se assinarmos padrões DDD e DDD, nossas entidades nunca terão dependências como um serviço faria. Pense em um pedido e em suas linhas de pedido correspondentes. As linhas de pedido podem existir em isolamento sem um pedido? Você pode ter uma linha de pedido de rouge? Não. A maior parte da identidade da linha de pedido é a própria ordem. A ordem é a entidade agregada .

Portanto, neste exemplo, o Show parece ser o seu agregado, enquanto o Episodes parece entidades filhas. Se este for o caso, você não teria nem mesmo um meio de carregar diretamente o Episodes do banco de dados. Eles sempre viriam com o Show . É por isso que você pode sentir que o ShowService é a maneira "correta" de resolver seu problema. Você provavelmente já ouviu algo nesse sentido em algum lugar da estrada. Talvez você já esteja muito familiarizado com DDD e tudo o que estou dizendo é para nada. De qualquer forma, achei que compartilharia.

O DDD é ótimo e oferece muita clareza sobre como você deve pensar sobre seu aplicativo e onde a lógica específica pertence, mas o DDD é difícil. Se o seu aplicativo é um aplicativo CRUD simples com pouca lógica sobre isso, eu evitaria DDD completamente. É muito trabalho e muito difícil de fazer bem.

Essa foi uma tangente, mas espero que ajude.

    
por 03.02.2017 / 05:11
fonte