Modelo “Clones” Adicionando complexidade ao projeto N-Tier MVC?

5

Eu estava discutindo uma estrutura de projeto minha com um amigo e ele apontou um ponto interessante sobre como minha arquitetura parece introduzir complexidade e abstração em minhas camadas, tendo "clones" de modelos existentes.

A estrutura do meu projeto, em geral, é assim:

[UIL] ---- Consumption / U.I. Layer (Just for the sake of completeness with respect to the architecture’s explanation)
    - Models (ViewModels & Mapping)
    - Controllers
    - Views

[API] ---- Service/API Layer (We call it the API layer because we use actual services from others that would be confusing if we called our stuff services & clash...so we call these classes with the suffix of Api (i.e. UserApi, ProductApi)) (coordinates the lower level calls & interactions into consumable higher level facades)
    - Api Models (Initial properties are the same to that of DTO models) (Rich Domain Models that utilize dependency injection to BLL api's, these are passed to Consumption / UI Layer if needed)
    - Interfaces(self-explanatory)
    - Adapters
    - Api's / Services
    - Mixins

[BLL] ---- Business Logic Layer (Domain)
    - Models (holds specific business logic rules & properties & engine references for corresponding api models that should not be publicly exposed)
    - Interfaces
    - Engines

[DAL] ---- Data Access Logic Layer
    - Models (Database matching anemic DTO's)
    - Interfaces (...)
    - Connections
    - Factories
    - Repositories
    - UnitOfWork's
    - Contexts

Ele observa que eu tenho vários "clones" dos modelos originais do meu DB / DAL pelo fato de cada um dos modelos DAL, BLL e API manter as mesmas propriedades que estão em si (geralmente não todos, mas todos eles se ligam através de alguns). No entanto, acho que eles progridem bem de anêmicos (apenas para interações de banco de dados) para complexos modelos de "domínio" com métodos totalmente liberados, propriedades totalmente expandidas, modelos vinculados, api de modelo vinculado (atrás de métodos / DI), validação, lógica de negócios api (por trás de métodos / DI), etc. Estes podem ser passados com segurança para qualquer camada de consumo para uso posterior ou para mapeamento para visualizar modelos.

  1. Eu não vejo uma razão para entupir meus modelos anêmicos de DAL com a lógica desses modelos, porque nada deve saber sobre meu DAL diferente da camada API / Serviço. Corrigir? Isso também quebra separação de preocupações desde agora o meu modelo DAL DTO agora mapeia para o banco de dados, lógica de negócios, visão, etc. e pode ser enviado de volta banco de dados ... ou de alguma forma, estou faltando alguma coisa?

  2. Se eu usar meus modelos DAL para tudo, minha camada de consumo / interface do usuário faria referência a DAL.Models.Product, por exemplo, e agora meu DAL é exposto. Esta é a antítese da separação de & desacoplando as camadas, certo? Se meu entendimento estiver correto, nada acima da camada de API / Serviço deve saber sobre qualquer coisa abaixo dele (ou seja, DAL, BLL e / ou outras camadas abaixo), correto?

  3. Os modelos do Api são mais totalmente personalizados para o que uma camada de consumo gostaria de ver versus um banco de dados (ou seja, sem id estrangeiro, classes "entidade", tinha claramente modelado comportamento via métodos, DI API, etc.), isso faz com que o front-end seja desacoplado do back-end se ele mudar, correto? Além disso, eles se conectam muito bem com ViewModels, precisando apenas usá-los como ViewModel ou através de um mapeamento rápido para um modelo de visualização.

Eu não estou dizendo que estou certo ou que meu amigo está certo, mas ele trouxe um ponto interessante que eu queria explorar. Até agora, a pesquisa é um tanto esporádica com pessoas em muitos campos diferentes.

    
por B1313 03.10.2017 / 04:31
fonte

1 resposta

3

Parece que seu amigo está sugerindo uma abordagem mais ADM (Anemic Domain Model).

Essencialmente, você só tem seu modelo DTO sem método e o utiliza em todas as camadas. Sua camada de dados não é exposta porque o modelo existe em seu próprio projeto / dll / class lib / namespace

Em vez de métodos no Modelo, seus métodos estão em Serviços. Então, em vez de Order.Purchase() , você tem SalesService.Purchase(order)

Você não precisa abandonar completamente a abordagem OOP, mas pode simplesmente usar seus Modelos de Negócios, com métodos incluídos, por toda parte. Afinal, estes são presumivelmente mapeados para os DTOs, Api Models, etc em sua configuração atual, de qualquer forma.

O problema dos 'clones' torna-se particularmente óbvio quando você tem uma arquitetura orientada a serviços. Eu vi sistemas com OrderPlatformCustomer, InventoryCustomer, ReportingCustomer, etc. todos, finalmente, leu do mesmo banco de dados, mas com campos ligeiramente diferentes, nomes de propriedades e métodos diferentes.

Torna difícil falar sobre "Um Cliente" porque ele não possui mais um único significado e conjunto de propriedades. Enquanto com uma abordagem ADM você reutiliza a mesma estrutura de dados em tudo. "Um cliente" sempre tem as mesmas propriedades e relacionamentos com outros objetos. Pode ser processado apenas de maneiras diferentes.

    
por 03.10.2017 / 14:07
fonte