Na minha opinião, não é absolutamente assim que se trata. E é uma violação do DRY.
A idéia é que o objeto de entidade / domínio no meio seja modelado para representar o domínio da melhor maneira e com a maior conveniência possível. Está no centro de tudo e tudo pode depender, pois o domínio em si não muda na maioria das vezes.
Se o seu banco de dados externo puder armazenar esses objetos diretamente, então mapeá-los para outro formato para separar as camadas não é apenas inútil, mas criar duplicatas do modelo e essa não é a intenção.
Para começar, a arquitetura limpa foi feita com um ambiente / cenário típico diferente em mente. Aplicativos de servidor de negócios com camadas externas gigantes que precisam de seus próprios tipos de objetos especiais. Por exemplo, bancos de dados que produzem SQLRow
objetos e precisam SQLTransactions
retornar itens de atualização. Se você usasse aqueles no centro, violaria a direção da dependência, porque seu núcleo dependeria do banco de dados.
Com ORMs leves que carregam e armazenam objetos de entidade, esse não é o caso. Eles fazem o mapeamento entre SQLRow
o domínio interno e o seu domínio. Mesmo se você precisar colocar uma @Entitiy
anotação do ORM em seu objeto de domínio, eu argumentaria que isso não estabelece uma "menção" da camada externa. Como as anotações são apenas metadados, nenhum código que não esteja procurando especificamente as verá. E mais importante, nada precisa mudar se você os remover ou substituir por uma anotação de banco de dados diferente.
Por outro lado, se você alterar seu domínio e criar todos esses mapeadores, precisará alterar muito.
Alteração: acima é um pouco simplificado e pode até estar errado. Porque há uma parte na arquitetura limpa que deseja que você crie uma representação por camada. Mas isso deve ser visto no contexto do aplicativo.
Ou seja, o seguinte aqui https://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html
O importante é que estruturas de dados isoladas e simples sejam passadas através dos limites. Não queremos trapacear e passar linhas de entidades ou de banco de dados. Não queremos que as estruturas de dados tenham qualquer tipo de dependência que viole a regra de dependência.
A passagem de entidades do centro para as camadas externas não viola a regra de dependência, mas elas são mencionadas. Mas isso tem uma razão no contexto da aplicação prevista. Passar entidades ao redor moveria a lógica do aplicativo para o exterior. As camadas externas precisariam saber como interpretar os objetos internos, teriam que efetivamente fazer o que as camadas internas, como a camada "caso de uso", devem fazer.
Além disso, também desacopla as camadas para que as alterações no núcleo não exijam necessariamente alterações nas camadas externas (consulte o comentário de SteveCallender). Nesse contexto, é fácil ver como os objetos devem representar especificamente a finalidade para a qual são usados. Além disso, essas camadas devem conversar entre si em termos de objetos feitos especificamente para os fins desta comunicação. Isso pode até significar que existem 3 representações, 1 em cada camada, 1 para transporte entre as camadas.
E há https://blog.8thlight.com/uncle-bob/2011/11/22/Clean-Architecture.html que aborda acima:
Outras pessoas temem que o resultado líquido dos meus conselhos seja muito código duplicado e muitas cópias repetidas de dados de uma estrutura de dados para outra nas camadas do sistema. Certamente também não quero isso; e nada que eu sugeri levaria inevitavelmente à repetição de estruturas de dados e a uma desordenada cópia de campo.
A IMO implica que a cópia simples de objetos 1: 1 é um cheiro na arquitetura, porque na verdade você não está usando as camadas e / ou abstrações adequadas.
Mais tarde, ele explica como ele imagina todas as "cópias"
Você separa a interface do usuário das regras de negócios passando estruturas de dados simples entre as duas. Você não deixa seus controladores saberem nada sobre as regras de negócios. Em vez disso, os controladores descompactam o objeto HttpRequest em uma estrutura de dados simples de baunilha e passam essa estrutura de dados para um objeto de interação que implementa o caso de uso invocando objetos de negócios. O interator reúne os dados de resposta em outra estrutura de dados de baunilha e os passa de volta para a interface do usuário. As visualizações não sabem sobre os objetos de negócios. Eles apenas olham nessa estrutura de dados e apresentam a resposta.
Nesta aplicação, há uma grande diferença entre as representações. Os dados que fluem não são apenas as entidades. E isso garante e exige classes diferentes.
No entanto, aplicado a um aplicativo Android simples como um visualizador de fotos em que a Photo
entidade possui cerca de 0 regras de negócios e o "caso de uso" que lida com elas é quase inexistente e está realmente mais preocupado com o cache e o download (esse processo deve ser IMO representado de forma mais explícita), o ponto de fazer representações separadas de uma foto começa a desaparecer. Tenho até a sensação de que a foto em si é o objeto de transferência de dados enquanto a camada principal da lógica de negócios está ausente.
Há uma diferença entre "separar a interface do usuário das regras de negócios passando estruturas de dados simples entre os dois" e "quando você deseja exibir uma foto, renomeie-a três vezes no caminho" .
Além disso, o ponto em que vejo esses aplicativos de demonstração falharem ao representar a arquitetura limpa é que eles acrescentam grande ênfase à separação de camadas para separá-las, mas ocultam efetivamente o que o aplicativo faz. Isso contrasta com o que é dito em https://blog.8thlight.com/uncle-bob/2011/09/30/Screaming-Architecture.html - ou seja,
a arquitetura de um aplicativo de software grita sobre os casos de uso do aplicativo
Não vejo essa ênfase na separação de camadas na arquitetura limpa. Trata-se da direção da dependência e do foco em representar o núcleo do aplicativo - entidades e casos de uso - em java idealmente simples, sem dependências externas. Não se trata tanto de dependências em relação a esse núcleo.
Portanto, se seu aplicativo realmente tiver um núcleo que represente regras de negócios e casos de uso e / ou pessoas diferentes trabalhem em camadas diferentes, separe-as da maneira pretendida. Por outro lado, se você está escrevendo um aplicativo simples, não exagere. 2 camadas com limites fluentes podem ser mais que suficientes. E camadas podem ser adicionadas mais tarde também.
BankAccount
mas com regras específicas do aplicativo, o que você pode fazer com essa conta.