Por que todos colocam controladores em uma pasta e exibem em outra?


36

Estou me preparando para tirar a curva do asp e entrar em uma estrutura mvc, asp.net mvc ou nancy. Onde quer que eu vá, vejo pastas para controladores / módulos e pastas para visualizações. Isso é apenas um reflexo pavloviano de arrumar as coisas por tipo, ou existe alguma sabedoria mais profunda operando? Tenho um pequeno projeto de prova de conceito em que armazeno os arquivos que provavelmente abrirei juntos, um conforto considerável. Como esses arquivos também podem se chamar, eles podem fazer isso com links relativos mais curtos, menos quebradiços. Esse padrão é desafiado pelo mvc, porque o caminho da pasta não corresponde mais automaticamente ao caminho da url e, no asp.net mvc, os modelos e o roteamento do projeto impõem os modos de exibição \ controllers \ schism.

Esta página da Microsoft apresenta o conceito de áreas. Pode ser lido como uma admissão de quão grandes aplicativos pesados ​​se tornam por causa dessa separação artificial.

As pessoas se opõem à "separação de preocupações", mas a separação de preocupações já é alcançada com arquivos de origem separados. Parece-me que não há ganho concreto ao pegar esses arquivos de origem fortemente acoplados e enviá-los para extremos opostos da estrutura de pastas?

Alguém mais está lutando contra isso? Alguma dica?


3
Você não acha lógico separar arquivos de código de back-end dos arquivos de exibição? Se já estamos tomando a direção, por que não colocar os arquivos CSS e JavaScript relevantes na mesma pasta também?
Alternatex

2
Se você obtiver o Resharper, a tecla F12 na chamada para Viewno controlador o levará à visualização e a primeira opção no menu do botão direito do mouse na visualização o levará ao controlador, e todo o problema com a falta de navegação desaparece.
Pete Kirkham

4
@ Alternatex Sinto muito, mas não vejo como um controlador é "back-end". Está fortemente acoplado às suas visualizações. A visualização não é boa sem um controlador, o controlador não é útil sem a visualização. Um dia você deseja excluí-los juntos. Isso para mim é o melhor teste do que pertence a uma pasta? A menos que alguém possa me mostrar um caminho melhor?
bbsimonbb

2
As vistas são uma camada de apresentação. Controladores são camadas que contêm serviços, que podem conter objetos do seu domínio, que contêm sua lógica de negócios e, portanto, contêm a lógica de back-end do seu aplicativo. As visualizações consistem apenas em condicionais triviais e loops simples para iteração sobre coleções; se suas visualizações contiverem outra coisa, você estará fazendo errado. Como na estrutura regular, você separou o back-end e o front-end, o que para mim é uma estrutura melhor do que a sugerida.
Andy

10
Portanto, não há falta de gente para me dizer que um controlador é louça, por isso vai para o armário da louça. As vistas são óculos para que eles entrem no armário de vidro. Eu sei que um controlador é louça, mas estou propondo que seria ótimo ter um armário de almoço e um armário de jantar, já que estamos falando de coisas que só são usadas no almoço ou no jantar.
bbsimonbb

Respostas:


38

Eu gostaria de dizer que é uma programação de cultos de carga , mas existem razões técnicas para essa estrutura. O Asp.Net MVC adotou uma convenção sobre a abordagem de configuração para quase tudo. Por padrão, o mecanismo de exibição do Razor pesquisa o Viewsdiretório para resolver qual exibição retornar do controlador. No entanto, existem alguns hacks para obter uma estrutura de projeto diferente e a Microsoft ainda fornece um recurso MVC chamado Areas para nos permitir criar uma estrutura de projeto mais sã. Você também pode implementar seu próprio mecanismo de exibição para especificar onde procurar visualizações.

Por que digo que é uma programação de cultos de carga e que você está certo sobre isso? O tio Bob me convenceu de que a estrutura de diretórios do projeto não deveria me dizer que é um aplicativo MVC. Deve me dizer que é uma fachada de loja, um sistema de solicitação de folga ou qualquer outra coisa. A estrutura e a arquitetura de alto nível devem nos dizer o que é isso, não como foi implementado.

Em suma, acredito que você esteja certo sobre isso, mas qualquer outra estrutura de diretório estaria simplesmente lutando contra a estrutura e confie em mim quando digo que você não deseja tentar fazer com que a estrutura do MVC do Asp.Net faça algo que não era. não foi projetado para fazer. É uma pena que não seja realmente mais configurável.


Para resolver rapidamente as preocupações de arquitetura, ainda acredito que os modelos de negócios (comercial, não visualizado) e o DAL devem residir em um projeto / biblioteca separado que é chamado a partir do seu aplicativo MVC.

É só que o controlador realmente está muito acoplado à vista e provavelmente será modificado juntos. Somos sábios em lembrar a diferença entre o acoplamento via dependência e o acoplamento lógico. Só porque o código teve suas dependências dissociadas não o torna menos logicamente acoplado.


11
A maneira abrangente de controlar onde a navalha procura pontos de vista está aqui . Eu posso apenas perseverar.
24416 bbsimonbb

3
Eu assisti tio bob, em x1,25, como sugerido. Fico pensando que, se os arquitetos de TI construíssem edifícios, todos estaríamos vivendo em pequenos grupos de balsas amarradas juntas, flutuando em algum lago. A vida não seria necessariamente mais simples.
bbsimonbb

11
Fica um pouco mais complicado. Para realmente co-localizar controladores e visualizações, você desejará resolver o caminho da visualização em tempo de execução, para incluir o espaço para nome do controlador. Aqui está como fazê-lo .
bbsimonbb

11
Também dê uma olhada no desenvolvimento de software orientado a recursos ( fosd.net ), para a contrapartida acadêmica do que o tio Bob está descrevendo.
ngm

11
Lei de Conway no trabalho. Tenho certeza que funciona na sua empresa @Flater. O layout padrão do MVC funciona em muitas empresas, mas eu ainda prefiro agrupar as coisas pela semântica do que pela sintaxe. As empresas em que trabalho foram organizadas em torno de produtos, em vez de papéis / funções. Eu acredito que esta é a raiz da minha preferência aqui.
precisa

9

Seja qual for o motivo, essa é uma prática ruim. É muito anti-OO porque pacotes ou pastas (como você quiser chamá-los), devem ter interdependências fracas. As classes (ou arquivos) dentro deles devem ter interdependências fortes.

Jogando todas as visualizações em uma pasta e todos os controladores em outra pasta, você está criando dois pacotes com acoplamento muito apertado. Isso vai contra o princípio de ter dependências fracas entre pacotes.

Uma visão e um controlador são duas metades de um todo e devem pertencer uma à outra. Você não teria um armário para as meias do lado esquerdo e outro para as meias do lado direito.


6

Para responder a sua pergunta "Por que todo mundo ...?" pergunta: Aqui estão algumas razões em potencial, embora eu não tenha muita certeza de qual combinação delas é uma causa real, uma vez que é realmente uma pergunta subjetiva

  • Para replicar a arquitetura lógica (modelo, exibição, controlador) com uma estrutura de pasta e namespace correspondente

  • Fora da convenção e conveniência de seguir o modelo de projeto do ASP.net MVC

  • Para agrupar por espaço para nome, pois a Controllers/pasta levará a um .Controllersespaço para nome

  • Pode ativar alguns cenários no DI / IoC em que as classes do controlador são consultadas / varridas apenas de um espaço de nomes que contém / termina com 'Controladores' (isso pode estar errado)

  • Para permitir que os modelos T4 digitalizem e andem com modelos e controladores de andaime para gerar visualizações

Você sempre pode criar e seguir sua própria convenção, se isso fizer sentido para o seu projeto, ninguém poderá / irá impedi-lo. Mas lembre-se de que, se você trabalha em um projeto grande e / ou em equipe grande, a convenção padrão conhecida por todos pode ser uma escolha melhor (embora não necessariamente a certa!)

Se sua convenção for mais fácil de seguir e não prejudicar a produtividade, faça-o de qualquer maneira! e talvez até escreva sobre isso um ou dois posts para socializá-lo com a comunidade de desenvolvedores e obter feedback


2

Um motivo para manter visualizações e controladores em diretórios separados é quando você tem desenvolvedores de front-end e back-end trabalhando em um projeto. Você pode impedir que os desenvolvedores de front-end acessem o código de back-end (por exemplo, para ajudar na conformidade com o PCI, restringindo quem tem acesso ao código confidencial).

Outro motivo é facilitar a criação de "temas" e a alternância de todos os modelos, fazendo uma pequena alteração no caminho da exibição.

Um terceiro motivo é ter um padrão de diretório simples ao especificar visualizações na estrutura MVC. É mais fácil especificar o subdiretório e o arquivo, em vez de um grande caminho longo para cada exibição.

O único "acoplamento rígido" deve ser:

  1. Variáveis ​​enviadas para a visualização pelo controlador.
  2. Campos de formulário ou ações na exibição, enviados de volta ao controlador.

Eu uso um controlador genérico e tento manter os nomes de variáveis ​​na exibição genérica, para que muitas visualizações possam usar o mesmo controlador e muitos controladores possam usar a mesma exibição. Por esse motivo, prefiro manter as opiniões totalmente separadas. O modelo é onde você pode diferenciar cada "coisa" em seu aplicativo - eles podem ser objetos com uma lista de propriedades e métodos para acessar / modificar essas propriedades.

Para código fortemente acoplado, uma abordagem que pode funcionar para você é manter todos os arquivos que fazem parte de um pacote ou "módulo" juntos em um diretório com espaço para nome. Em seguida, você pode usar um script para copiar ou "compilar" seus modelos brutos no diretório principal "views". Por exemplo:


    lib/my-namespace/my-package/
        -> controllers/
        -> models/
        -> views/
            -> theme/
               -> template-name1
    app/compiled_views/theme/
        -> url/path/template-name1

Infelizmente, se você deseja alterar a estrutura de um tema existente, há mais inserção e exclusão de diretórios de pacotes para atualizar as visualizações.

Considere que as visualizações são apenas uma maneira de formatar dados, sejam eles json, xml, csv ou html. Isso ajuda especialmente se você deseja que seu aplicativo também funcione como uma API. Tente desacoplar a visualização dos dados, usando nomes de variáveis ​​genéricos, para que você possa usar o mesmo modelo para muitos controladores ou modelos (ou use include para minimizar a quantidade de código que você precisa manter).


1

Nem sempre todo mundo faz isso. Por exemplo, o framework Django do python tem o conceito de um aplicativo, onde os submódulos do seu aplicativo vivem em seus próprios diretórios com seus próprios modelos, visualizações e modelos (as visualizações são o que o Django chama de controladores essencialmente). Por acaso, prefiro esse modo de fazer as coisas, porque isso significa que posso facilmente empacotar um "aplicativo" e reutilizá-lo nos projetos, incluindo-o na lista de aplicativos nas configurações dos meus projetos. Também é mais fácil descobrir onde estão as diferentes partes. Se eu olhar para o arquivo urls.py e ver algo como url(r'^users/', include('my_site.users.urls')), sei que o módulo my_site.userscontém todo o código que lida com os usuários. Sei examinar os módulos my_site.users.viewse my_site.users.modelsquando quero ver como os usuários são criados e autenticados. Eu sei que todas as minhas rotas estão definidas my_site.users.url.

Além disso, se for genérico o suficiente, provavelmente posso usar esse módulo em outros sites apenas alterando a configuração ou empacotando-o como uma biblioteca e publicando-o como OSS.


1

Lembre-se de que é a maneira recomendada pela Microsoft de manter os controladores e as visualizações em uma pasta diferente; muitos seguiriam a estrutura recomendada,

  1. Um motivo pode ser que os controladores sempre não tenham um relacionamento individual com as visualizações, especialmente as visualizações parciais podem ser compartilhadas entre os controladores.
  2. Outro motivo pode ser que, quando o projeto cresce, convém puxar os controladores e os testes de unidade para outro (s) projeto (s), mas é muito difícil fazer o mesmo para as visualizações e as visualizações / js / css pertencem uma à outra à medida que se referem.

Dito isto, existem muitos posts sobre como fazer do seu jeito, como esse .


"é a maneira recomendada pela Microsoft" ... Você pode esclarecer o que você quer dizer com isso? Existe um artigo real e oficial da MS sobre isso? Ou isso é apenas a configuração padrão do projeto para um aplicativo MVC? E, se você está baseando isso no último, não é possível que a configuração padrão do projeto MVC seja o que é porque é como "todo mundo" faz isso?
Svidgen

11
Com base no artigo msdn.microsoft.com/en-us/library/… , diz "Controladores, o que é recomendado" e assim por diante para as visualizações, etc.
Low Flying Pelican

0

Para o registro

Por que digo que é uma programação de cultos de carga e que você está certo sobre isso? O tio Bob me convenceu de que a estrutura de diretórios do projeto não deveria me dizer que é um aplicativo MVC. Deve me dizer que é uma fachada de loja, um sistema de solicitação de folga ou qualquer outra coisa. A estrutura e a arquitetura de alto nível devem nos dizer o que é isso, não como foi implementado.

Pergunta: Quem tem acesso ao código? Programadores. Os usuários finais se preocupam com o código ?. Não. E o que um programador faz, codifica. Ou, mais especificamente, classes baseadas em tipos (controladores, serviço, modelo e assim por diante). Portanto, faz sentido e é fácil depurar um código, se você conseguir encontrar um código com base no tipo de código, e não no comportamento do código. Além disso, digamos que um projeto de equipe, um é responsável pelo controlador, outro pelo modelo, outro pelo dao e outro pela vista. É fácil separar o projeto em partes. Um bom código é um código fácil de depurar, não um código sugar de sintaxe. Tio Bob está errado de novo.

Tentar imitar o comportamento do projeto (uma frente de loja) é um culto à carga.


3
Quando eu codifico, me importo mais com os recursos, não com os tipos. Quando vejo um recurso que não está funcionando como esperado, sei que algo está errado no código relacionado a esse recurso, embora não saiba necessariamente que tipo de código é esse.
Pare de prejudicar Monica

11
“Digamos que um projeto de equipe, um seja o responsável pelo controlador, outro o modelo, outro o dao”. Essa equipe terá dificuldade em enviar qualquer coisa e, quando o fizer, terá um custo muito maior em despesas de comunicação e bugs.
precisa

Conforme estabelecido em uma cadeia de comentários com a resposta aceita, você tem um ponto, mas apenas em certos casos. Quando uma empresa se concentra nos projetos MVC que vende para muitos clientes variados, manter uma estrutura MVC faz sentido para reutilização. Quando uma empresa se concentra em um nicho (por exemplo, lojas virtuais) e possivelmente usa muitas tecnologias diferentes, faz mais sentido ter uma estrutura orientada para lojas virtuais. Esta é uma aplicação prática da lei de Conway . O código (e, portanto, também a estrutura do projeto) deve seguir a estrutura da empresa.
Flater

@RubberDuck: Você pode argumentar sobre custos adicionais de qualquer maneira. Você está certo que, quando pessoas diferentes fazem componentes técnicos diferentes, você aumenta a comunicação da lógica de negócios. No entanto, se você tem pessoas diferentes implementando totalmente recursos diferentes, pode ter aumentado os custos para garantir que todos estejam a bordo (qualificados + concordando) usando a mesma abordagem técnica. De qualquer forma, você precisa de uma sobrecarga de comunicação para garantir que as pessoas trabalhem juntas.
Flater

Sim, e as transferências sempre custam mais do que ter um único par de desenvolvedores implementando um recurso de ponta a ponta no IME.
precisa saber é o seguinte
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.