Devo organizar minhas pastas por domínio comercial ou por domínio técnico?

19

Por exemplo, se estou usando alguma arquitetura semelhante ao MVC, qual estrutura de pastas devo usar:

domain1/
    controller
    model
    view
domain2/
    controller
    model
    view

Ou:

controllers/
    domain1
    domain2
models/
    domain1
    domain2
views/
    domain1
    domain2

Eu deliberadamente deixei de fora as extensões de arquivo para manter esta questão independente de idioma.

Pessoalmente, eu preferiria separar por domínio comercial (pressentimento), mas vejo que muitas / muitas estruturas são separadas por domínio técnico. Por que eu escolheria um sobre o outro?

Florian Margaine
fonte
2
estruturas são direcionadas a desenvolvedores, não a usuários corporativos. Os desenvolvedores são esperados para ser mais confortável com a abordagem orientada tecnicamente e estruturas levar isso em conta - que pode ser a razão para o que você observa
mosquito

Respostas:

15

Eu acho que isso depende do projeto específico.

Por exemplo, se os diferentes domínios de negócios forem totalmente independentes um do outro, eu organizaria por domínio de negócios.

Mas se houver código compartilhado entre os domínios de negócios, ou melhor, os domínios de negócios são variantes diferentes da mesma base de código, então parece mais lógico organizar por domínio técnico. E se você usar qualquer tipo de linguagem orientada a objetos, provavelmente poderá subclassificar seus controladores genéricos, modelos etc. nos arquivos específicos da sua empresa para torná-los mais finos.

Também existe um caminho (dourado) entre os dois - retire o código compartilhado em seu próprio domínio e use-o em outros domínios. Isso fornece um layout otimizado, mas permite código compartilhado entre domínios de negócios.

Domain1              # This domain changes bits of standard MVC code
  controllers
  models
  views
Domain2              # this domain only modifies views, all else is standard
  views
Shared               # Here is the better part of code base
  controllers
  models
  views

PS. Eu acho que a maioria das estruturas se organiza por domínio técnico, apenas porque elas esperam que você misture domínios de negócios diferentes em um único projeto somente se você tiver código compartilhado e, caso contrário, criaria projetos separados.

EDITAR:

Por exemplo, suponha que haja um aplicativo Web que lide com o armazém de uma empresa. De forma genérica, isso pode se aplicar a muitas empresas, mas cada uma delas pode ter algumas especificidades que não são atendidas e as proíbe de comprar. Por exemplo, uma delas implantou tablets nas empilhadeiras e precisa de uma visualização especial para elas enquanto outra deseja para organizar itens em três níveis, em vez do padrão de dois.

É claro que você poderia elaborar o projeto para cada uma dessas empresas. Mas se a estrutura / linguagem permitir, você poderá usar subclasses ou plug-ins etc. para personalizar partes do projeto genérico de acordo com as necessidades de cada cliente e organizá-las nos layouts de Domínio Comercial.

Por exemplo, se um projeto genérico exportar para JSON apenas o próprio item, o Domain1 poderá subclassificar o controlador e exportar também problemas de entrega recentes.

E se você descobrir posteriormente que o Domínio1 tem um componente que também é válido para o Domínio2, você pode extrair a versão genérica para o Compartilhado.

Como você disse, muitas estruturas se organizam por domínio técnico e é isso que eu usei agora, apenas porque meu FW de escolha facilita isso. Mas com um pouco (ou muito) de graxa de cotovelo, acho que poderia reescrever os caminhos de inclusão para dar suporte ao layout do Business Domain também.

Laas
fonte
Eu acho que a idéia é ótima, mas não consigo imaginar um exemplo prático. Você poderia dar uma simples, mas esclarecedora?
Florian Margaine 18/10/12
@FlorianMargaine - vou dar um exemplo do mundo real. Sites imobiliários. No meu último emprego, vendemos vários sites imobiliários para muitos clientes. Tínhamos um banco de dados centralizado para todos os mais de 50 clientes. Cada administrador de back-end usou um conjunto compartilhado de módulos. Cada lado do cliente usava imagens e navegação exclusivas. Cada página de pesquisa e pesquisa utilizava módulos compartilhados, exceto nos casos em que um cliente desejava recursos únicos. Para essas pontuações, dividimos o código e fornecemos a eles seu próprio módulo. (Drawback: Upgrades tinha de ser feito nos moduels comuns e duplicados nos os únicos módulos)
Michael Riley - AKA Gunny
8

Eu acho esclarecedor perguntar: "O que é mais provável adicionar regularmente, mais domínios ou mais divisões técnicas?" Qualquer que seja a resposta, coloque isso no nível superior.

Na maioria dos casos, sua arquitetura técnica se solidifica mais rapidamente que seu domínio. Isso significa que você deve organizar primeiro o domínio e depois o componente arquitetural. O motivo é que, quando algo em um domínio muda, pode ser necessário adicionar ou alterar vários componentes técnicos nesse domínio, mas espero que seja localizado e não se espalhe muito para outros domínios.

Se você alterou sua estrutura de GUI, isso significa que suas alterações serão espalhadas por todo o aplicativo, mas, novamente, você raramente altera sua estrutura de GUI, mas sempre muda sua lógica de domínio.

Mantenha as coisas juntas, se é provável que elas mudem ao mesmo tempo.

Scott Whitlock
fonte
O melhor conselho, mas não vejo como prever que tipo de domínio vou adicionar mais.
Florian Margaine 18/10/12
A última frase diz respeito.
Hakan Deryal 18/10/12
@FlorianMargaine - Não acho que o "tipo" de domínio seja importante. Se você adicionar domínios mais do que adicionar novas "coisas" técnicas, agrupe tudo por domínio primeiro.
10138 Scott-Locklock-
3

Existe outra alternativa e que está movendo as partes separadas em plugins. O CakePHP faz isso por exemplo. Isso permitirá que você gere partes completas do MVC que são reutilizáveis ​​e que você pode classificar por qualquer lógica que desejar.

Seu aplicativo principal irá apenas usá-los e vincular a eles.

Basicamente, sua pergunta também é sobre coesão e acoplamento. Você deseja que as partes separadas funcionem da maneira mais independente possível. Dessa forma, você obtém código testável e reutilizável.

Levando isso em consideração: se você se dividir por domínio, como reutilizaria partes do seu aplicativo? Por exemplo, faça uma loja virtual: uma solicitação é fornecida para / orders / view / 1, portanto você precisa mostrar o pedido nr. 1. Vá para / orders / controllers / order_controller Se você separou o domínio por produtos e pedidos, já precisaria de partes do outro "domínio".

Lá, você pode começar a interagir com as coisas, mas as coisas prováveis ​​são, na maioria dos negócios, muito coesas. Se você adotar a abordagem técnica. Por exemplo, você pode ter um plug-in que lida com pedidos. Você coloca objetos de Produto no seu aplicativo central. Dessa forma, você pode testar o plug-in facilmente, basta criar um objeto Produto com um nome e preço e enviá-lo.

O plug-in fará exatamente o que precisa. Depende da entrada e não de outras "partes / domínios / áreas".

Luc Franken
fonte
Boa ideia. É essencialmente de cima para baixo da minha resposta. Coloquei o código compartilhado no topo e basicamente conectei os detalhes do domínio. Você coloca o domínio no topo e conecta o código compartilhado. Penso que ambas são igualmente boas abordagens em relação ao desacoplamento e testabilidade.
Laas
2

Microsoft ASP.Net MVC 3 tem o conceito de "Áreas". Quando você introduz "Áreas" em seu projeto MVC, elas são divididas da seguinte maneira:

area1/
   models
   views
   controllers
area2/
   models
   views
   controllers

Eu achei isso bastante natural. Uma área é um "pedaço grande" de um projeto, e trabalhar em uma unidade independente apenas faz muito sentido.

Usamos namespaces para combinar, FWIW.

gahooa
fonte
2
Obrigado por sua contribuição, mas como isso responde à minha pergunta? (Comparando as duas soluções)
Florian Margaine
@FlorianMargaine: Estou ilustrando como a Microsoft fez isso, com a suposição (possivelmente falha) de que eles colocaram muito esforço de engenharia na escolha da maneira mais sensata. Espero que ele dê alguma entrada.
gahooa
Ok, mas essa é a maneira orientada para os negócios que mostrei na minha pergunta ...
Florian Margaine 25/10/12
1

Da minha experiência pessoal com uma loja virtual composta por 300.000 linhas de código, eu sempre organizava por domínio comercial. Dessa forma, você não pode apenas obter uma visão geral rápida de todas as classes relevantes ao trabalhar em uma área funcional; em Java, você também pode fazer uso da visibilidade do pacote.

Alguns detalhes para aqueles que estão interessados: Quando o projeto foi iniciado 5 anos atrás, os desenvolvedores criaram a seguinte estrutura de pacotes:

com
  example
    web
      struts
        action
        form
      shared
      functionality1
      functionality2

Cada função de loja, como carrinho de compras, pesquisa de produtos, etc. consiste em várias ações, cada uma com sua própria classe de formulário (estrutura determinada pela estrutura MVC). Acabamos com mais de 200 classes no pacote de ação, cada uma completamente separada da classe de formulário associada. O pior é que as ações não implementam muita lógica, mas chamam serviços específicos de função que residem em outro pacote.

Sugeri e convenci a equipe de que deveríamos mudar para a organização de pacotes por domínio comercial. O raciocínio é simples: se você realmente deseja ver uma lista de todas as ações, pode simplesmente abrir a exibição da hierarquia de tipos de qualquer IDE decente. No entanto, o que o IDE não pode fazer é deduzir o domínio comercial ao qual uma classe pertence. Além disso, essa abordagem permite tornar públicas apenas as classes necessárias para diversas funcionalidades, mantendo o restante na visibilidade do pacote.

Jens Bannmann
fonte
0

Concordo que muitas estruturas se separam por domínio técnico e, portanto, geralmente começo dessa maneira ao usar uma nova estrutura. No entanto, eu sempre uso o domínio comercial como o principal nível de organização de pastas.

Pessoalmente, acho que é muito mais fácil manter o Foo Controller e o Foo Repository ou o que quer que esteja juntos do que ir e voltar entre a pasta do Controlador e a pasta do Repositório quantas vezes eu precisar trabalhar nos dois ao adicionar recursos ao Foo. Em projetos maiores, isso é ainda mais importante, pois a distância entre as pastas técnicas pode ser grande e tornar-se uma perda notável de tempo durante o desenvolvimento.

quentin-starin
fonte