Orientação da estrutura do projeto de aplicativo em camadas MVVM, DDD e WPF

17

Estou tentando configurar a estrutura do meu aplicativo no VS e quero "tentar" e fazer a prova futura para um nível razoável. Este aplicativo será uma reescrita do WPF de um aplicativo Winform antigo que não seguiu nenhuma convenção. Sem Camadas, Camadas, Acrônimos, etc ...

É um aplicativo corporativo bastante amplo. Planejei usar o Linq To SQL como meus DBs e provavelmente será sempre o MS SQL. Também tenho um conjunto de habilidades existentes.

Quero seguir o MVVM e o DDD da melhor maneira possível, mas fico confuso com a estrutura do meu aplicativo ao combiná-los. Deixe-me tentar ilustrar com alguns exemplos.

Quando sigo o MVVM, minha estrutura de pastas pode ficar assim:

Views
Models
ViewModels
Helpers

mas como isso se encaixa em uma abordagem simplificada em camadas do DDD, na qual minha estrutura do projeto pode se parecer com isso:

MyApp.UI
MyApp.Domain
MyApp.Data

Coloco Modelsna camada Domínio ou tenho 3 versões do Say Person? Isso leva a outra questão de onde eu colocaria meu Repositório e mapeamentos do Objeto DB no Objeto Domínio? Eu assumiria Data ...

Views Eu recebo iria na interface do usuário, mas seria ViewModels também?

Por fim, onde eu incorporaria minha lógica de negócios?

Encontrei o seguinte no CodePlex, DDD Example , e isso tem sido útil, mas parece ser para um aplicativo da Web, embora isso não importe e seja minha ignorância brilhando.

Não me interpretem mal, eu sei que posso ter quantas pastas e chamá-las como quiser. Estou tentando descobrir onde colocar as coisas para que elas possam ser escaláveis, e não como esses lugares são necessariamente chamados.

O coração da minha pergunta pode ser mostrado assim.
Eu tenho tblPersonobjeto gerado por *.dbml. Isso é óbvio e pertenceria à minha camada "Dados".
Agora eu teria chamado Model, DTO, Domain Model ou o que for chamado em uma camada separada (projeto?) Person. Eu precisaria de uma Mapperpara Persona tblPersonque eu não tenho certeza de onde colocar.
Então, terei um ViewModel para, digamos, EditPersonque teria suas próprias propriedades, Personmas possivelmente mais.
Finalmente, eu teria uma View que estava vinculada a esse ViewModel ....

Para ficar claro que o parágrafo está repleto de minhas suposições e suposições e espero que alguém ajude a limpar o ar para mim ou a oferecer idéias para que, daqui a seis meses a um ano, eu não esteja me chutando mais do que preciso.

Paladino Refratado
fonte
O Linq To SQL não é adequado para projetos maiores. Use o Entity Framework ou ORM diferente como o nHibernate. Além disso, esse aplicativo é apenas para cliente ou servidor-cliente?
Euphoric
É um aplicativo somente para cliente WPF. Além disso, você poderia explicar por que sente que o L2S não é adequado para um aplicativo de tamanho médio ou maior quando minha única fonte de dados é o MS SQL?
Paladino Refractado em

Respostas:

5

MVVM é um padrão de interface do usuário e é usado em um cliente.

As partes do domínio no DDD usadas no cliente provavelmente são (parte do) Modelo

O View e o ViewModel são apenas clientes.

Coloquei Repositórios no (ou próximo) do Modelo porque eles sincronizam o Modelo com o back-end.

Sim, muitas vezes isso resultará em várias classes Person em diferentes namespaces. Eles podem começar muito semelhantes, mas podem acabar muito diferentes após algumas iterações ou lançamentos.

EDITAR

Esclarecer a parte sobre Repositórios e explicar mais sobre o posicionamento da Business Logic

Se você estiver criando um sistema que contém um cliente separado e os repositórios do lado do servidor / back-end podem ser usados ​​no cliente e no servidor. No cliente para fornecer uma abstração do (s) servidor (es) e no servidor para fornecer uma abstração de outros servidores e fontes de dados. É apenas um padrão.

Quanto às regras de negócios: se você as usar no cliente, certifique-se de aplicá-las também no servidor. Nunca confie em um cliente. As regras de negócios no cliente permitem validação rápida de entrada e evitam viagens de ida e volta ao servidor.

Eu acho que o DDD pertence ao lado do servidor e 'vaza' para o cliente.

ER não
fonte
2

Você tem a direção certa ao escolher o padrão de design MVVM para o aplicativo WPF.

Do I put the Models in the Domain layer?

Sim, seus modelos podem ser colocados no domínio

Where would I put my Repository and mappings of DB Object to Domain Object?

Seus repositórios podem ser colocados na camada em que seu domínio está localizado. Seus objetos de mapeamento (também chamados de DTOs - objetos de transferência de domínio) devem ser colocados em sua camada de serviço e você pode usar uma poderosa ferramenta de mapeamento AutoMapper para mapear facilmente seus objetos de domínio para DTOs.

ViewModels also?

Seu ViewModels deve ser colocado no lado do cliente (camada). Você pode construir seus modelos de exibição a partir de um ou mais DTOs, dependendo da sua exibição.

Em relação ao DDD , sugiro ler sobre isso e esclarecer que você realmente precisa ter um padrão de design orientado a domínio. Aqui está uma discussão que 95% de todos os aplicativos de software se enquadram nas categorias “não tão boas para usar DDD”.

Edit: a referência foi adicionada acima e obrigado pelo @Den!

Yusubov
fonte
por favor, comente quando estiver em votação baixa.
Yusubov 03/08/2012
1
Os fanboys do DDD querem usá-lo em qualquer lugar. Link relacionado: stackoverflow.com/questions/810606/is-ddd-a-waste-of-time
Den
@ Den, obrigado pelo link! eu estava planejando procurá-lo.
Yusubov 03/08/2012
1

Antes de nos aprofundarmos no que vai aonde, vamos falar sobre o que cada camada deve estar fazendo.

O ponto de venda do MVVM é a ligação entre a visualização e o modelo de visualização. O objetivo aqui é eliminar a lógica dentro da visualização.
Como a View, o Model deve ser bem leve e usado apenas para acessar as informações (dados) necessárias para o modelo de exibição operar. O Modelo pode combinar o acesso a diferentes fontes de dados, mas não deve ter lógica de negócios. Na maioria dos casos, você tem um único armazenamento de dados a ser atingido. Em alguns casos você não. Quando não o fizer, é apropriado usar o Modelo para ocultar a fonte dos dados da VM.

Um ponto implícito do MVVM é que os dados já estão armazenados e seu projeto não é responsável por manter sua organização. Alguns projetos têm a sorte de se safar dessa suposição, a maioria dos projetos em que trabalhei não teve tanta sorte. Basta dizer que Data é outra camada que teremos que enfrentar.

Eu colocaria meu projeto assim:

 project.Views
 project.ViewModel
 project.Model
 project.DataStructs

e essa camada pode ser adicionada conforme necessário:

 project.Helpers

Estou separando os Helpers do restante da pilha para que não se confunda como sendo uma camada da pilha de aplicativos.

Isenção de responsabilidade: não sou especialista em DDD, mas entendo a essência geral e vejo o valor dessa abordagem.

Seu domínio será o conjunto de problemas que você está considerando.
Os modelos de domínio corresponderão principalmente aos exibição que você cria; um pouco dentro das Views; e um pequeno pedaço dentro do Model / DataStructs.

Então, como isso vai dar certo?
Se você puder alterar as estruturas de dados existentes, as novas que você criar deverão se correlacionar com o problema que você está tentando resolver. Tem um objeto de cliente? Então você deve ter algumas tabelas relacionadas ao Cliente. Recebeu faturas ou produtos? Mesma história - tabelas e estruturas que são mapeadas para esses objetos de negócios devem ser criadas.

O domínio será expresso através dos seus objetos ViewModel e das visualizações que você apresentar desses objetos. Se você precisar editar os registros do Cliente, terá uma VM para lidar com essa tarefa.

Sobre suas perguntas:

  1. Não tente sobrepor DDD ao MVVM. Isso simplesmente não vai funcionar. DDD não é um padrão de layout, é uma abordagem para visualizar seu problema geral.
  2. Repositório e Mapeamentos permanecerão em project.Data ou project.Model conforme apropriado.
  3. Não tenha uma camada chamada UI, a menos que você queira chamar project.Views.
  4. A lógica de negócios será exibida no modelo de exibição.

fonte
1
Ok, algumas, provavelmente ignorantes, perguntas de acompanhamento. (1) você tornaria cada um deles um projeto separado ou apenas pastas (por exemplo, Project.View etc.)? (2) DataStructs é onde você colocaria os * .dbml's ou Project.Data? (3) Então, na sua opinião, eu não teria um Project.Domain? Eu vi que usado algumas vezes é por isso que pergunto.
Palatino refratado
@RefractedPaladin - 1) apenas pastas dentro do projeto. Você pode argumentar que Data deve ser seu próprio projeto. Do ponto de vista da manutenção, qualquer uma das maneiras é equivalente. 2) sim, exatamente. 3) não, eu não teria uma pasta .Domain. Na IMO, nosso trabalho é mapear o aplicativo para o domínio do problema de negócios. Portanto, o domínio permeia todas as camadas do projeto.