Eu desenvolvi para vários projetos de aplicativos da web nos últimos 3 anos, tanto pessoais quanto no trabalho, e não consigo descobrir se é possível que pelo menos alguma lógica de negócios não acabe na camada de visualização do aplicativo.
Na maioria dos casos, haverá problemas como "Se o usuário selecionou a opção x, o aplicativo deve permitir que ele forneça informações para y; caso contrário, ele deve fornecer as informações z". Ou faça alguma operação AJAX que aplique algumas alterações ao modelo, mas NÃO as confirme até que o usuário solicite explicitamente. Esses são alguns dos problemas mais simples que encontrei e não consigo descobrir como é possível evitar lógica complexa na exibição.
A maioria dos livros que li descrevendo o MVC geralmente mostra alguns exemplos muito triviais, como operações CRUD que apenas atualizam dados no servidor e os exibem, mas CRUD não é o caso nos aplicativos mais avançados.
É possível obter uma visão sem lógica de negócios?
fonte
Respostas:
Acho que essa é uma pergunta enganosamente difícil de responder. (Pergunta instigante!)
Teoricamente, sim, dependendo do que definimos como lógica de negócios. Na prática, a separação estrita se torna muito mais difícil e talvez até indesejável.
A separação de preocupações é uma ótima maneira de pensar na criação de software: fornece idéias sobre onde colocar o código e fornece aos mantenedores uma boa idéia sobre onde procurar o código. Argumentarei que é basicamente impossível para os humanos criar software de trabalho sem separação de preocupações. Nós precisamos disso.
Mas, como em todas as coisas, existem trade-offs. A melhor localização conceitual pode não ser a melhor localização por outros motivos. Talvez exista muita carga no seu servidor da Web, então você adiciona algum javascript às suas páginas da Web para detectar erros de entrada fáceis antes que eles atinjam o servidor; agora você tem alguma lógica de negócios em sua opinião.
A visão em si, por si só, não tem valor sem a lógica de negócios. E para ser eficaz no uso e exibição, implícita ou explicitamente, a exibição terá algum conhecimento dos processos de negócios que estão por trás dela. Podemos limitar essa quantidade de conhecimento e isolar partes dele, mas considerações práticas muitas vezes nos forçarão a "romper" a separação de preocupações.
fonte
The best conceptual location may not be the best location for other reasons
: Bravo !!Eu costumo fazer isso: se o usuário selecionou a opção x, a visualização chama
Em seguida, o controlador ativa y na exibição:
A visualização notifica o controlador do que acontece sem decidir nada.
fonte
Eu questiono se os exemplos que você descreve são realmente lógica de negócios. Os exemplos que você descreve são operações que podem ser executadas no sistema. Foi assim que você escolheu apresentar as opções ao usuário que talvez pareçam estar executando a lógica de negócios na exibição.
Do ponto de vista "View", ele fornece apenas InfoY ou InfoZ ao sistema. Só porque sua implementação de interface do usuário está fazendo algumas atualizações dinâmicas com base na escolha de um operador (por exemplo, ativar o InfoY ou o InfoZ) não torna a funcionalidade lógica de negócios. É realmente ver a lógica de implementação. Você poderia muito bem ter simplesmente dado ao operador a opção de inserir o InfoY ou o InfoZ sem toda a ativação. Nesse contexto, você ainda consideraria a lógica de negócios? Caso contrário, o mesmo se aplica para ativar / desativar dinamicamente os campos de informações.
O mesmo vale para o exemplo de confirmação. Estas são duas operações separadas que o sistema requer para funcionar corretamente. Sua visualização deve poder iniciar as ações adequadas para executar a funcionalidade desejada. Saber usar o sistema significa que a lógica de negócios está vazando? Posso ver como alguém pode dizer sim, mas se você acredita dessa maneira, a realidade é que não existe separação entre lógica de negócios e nada. Você precisa saber com o que o sistema está fazendo / trabalhando para realizar algo significativo. Caso contrário, seria fácil criar um único View and Controller genérico que funcione com todos os aplicativos MVC concebíveis. O que sabemos é impossível.
Resumindo, acho que sua definição de lógica de negócios não é a mesma que a de outros.
fonte
Eu trabalho desta maneira (Struts2 + Hibernate):
O My Struts Actions é responsável apenas por mostrar informações no navegador da web. Não estou pensando.
Usuário -> Ação -> Serviço -> Repositório -> Acesso a Dados
Ou:
Quero ver -> Como ver -> O que fazer -> Como obter -> Onde obter
Então, na primeira camada (a visualização), tenho algo como:
Como você vê, minha "visão" não pensa. Ele está solicitando um serviço (para gerenciar cursos), um curso específico. Esse serviço pode fazer muito mais, como relatórios, seraches e assim por diante. Os resultados são sempre uma lista ou um objeto específico (como o exemplo). Os serviços são a máquina real, aplicam regras e acessam o Repositório (para gerenciar os dados).
Portanto, se eu colocar meus Serviços, Repositórios e DAOS em diferentes bibliotecas, posso usá-lo mesmo em um programa baseado em texto ou em um sistema de desktop baseado em Windows sem alterar nada.
O serviço sabe o que fazer, mas não sabe como mostrar. A exibição sabe como mostrar, mas não sabe o que fazer. O mesmo acontece com Serviço / Repositório: O serviço envia e solicita os dados, mas não sabe onde os dados estão e como levá-los. O repositório "compõe" os dados brutos para objetos de negócios, para que o Serviço possa trabalhar.
Mas o Repositório não sabe nada sobre o banco de dados. O tipo de banco de dados (MySQL, PostgreSQL, ...) refere-se ao DAO.
Você pode alterar o DAO se desejar alterar o banco de dados e ele não deve afetar as camadas superiores. Você pode alterar o repositório se desejar atualizar seu gerenciamento de dados, mas isso não deve afetar o DAO e as camadas superiores. Você pode alterar os Serviços se quiser alterar sua lógica, mas isso não deve prejudicar as camadas acima nem abaixo.
E você pode alterar qualquer coisa à vista, mesmo a tecnologia (web, desktop, texto), mas isso não implica em contato com nada abaixo.
A lógica de negócios é serviço. Mas como interagir com isso é ver. Qual botão para mostrar agora? O usuário pode ver este link? Pense que seu sistema é um programa baseado em console: você deve negar se o usuário errado escolher
#> myprogram -CourseService -option=getCourse -idCourse=234
ou parar com ele para pressionar as teclas para escrever este comando?Conversando em sistemas baseados na Web (Struts + JavaEE) Eu tenho um pacote de controlador de GUI separado. Na exibição Ação, dou ao usuário logado e a classe me fornece os botões (ou qualquer elemento de interface que eu queira).
E
Lembre-se de manter isso fora dos serviços. Isso é coisa do VIEW. Mantenha-o nas ações do Struts. Todas as interações da interface devem ser totalmente separadas do código comercial real; portanto, se você portar o sistema, será fácil cortar o que não será mais necessário.
fonte
Essa é a lógica do modelo, não a visão. Pode ser um "modelo de exibição", criado especificamente para suportar a interface do usuário, mas ainda é a lógica do modelo. A sequência de controle é:
inputY.enable(model.yAllowed()); inputZ.enable(model.zAllowed());
UI View Controller Model |.checkbox X checked.> | | | | | .. X selected ...>| | | | |-----> set X ------->| | | | | | |< .............state changed ............| | | | | | |-------------- Get state --------------->| | | | | | |<----------- new state ------------------| | <-- UI updates ------|
Este é o padrão clássico do MVC. É possível testar completamente a lógica do modelo separada da interface do usuário. O controlador e a visualização são muito finos e fáceis de testar.=== Em resposta a Dunk ===
O modelo em um padrão MVC da interface do usuário (geralmente) não é um modelo de objeto de negócios. É apenas o modelo para o estado da interface do usuário. Em um aplicativo de desktop, ele pode conter referências a vários modelos de negócios. Em um aplicativo Web 2.0, é uma classe Javascript que mantém o estado da interface do usuário e se comunica via AJAX com o servidor. É muito importante poder escrever testes de unidade sem interrupção do modelo de estado da interface do usuário, pois é onde a maioria dos bugs da interface do usuário é encontrada. A vista e o controlador devem ser conectores muito finos.
fonte
Uma lógica de negócios é mais parecida
If X then return InfoType.Y
; a interface do usuário exibirá campos com base no resultado retornado pelo domínio.Se a interface do usuário exigir uma lógica comercial, delegar a opção ao domínio. A interface do usuário simplesmente agirá de acordo com a decisão.
fonte
Existem entradas que têm valores obrigatórios com base condicional. Na maioria dos ambientes de GUI, há muitas opções de como lidar com entradas, especialmente o tempo. A opção selecionada (neste caso x) precisa ser processada, então envie-a para o controlador. Envie quando os usuários deixarem o campo de entrada. Espere até eles clicarem em outro objeto ou clicar em salvar. Não importa para a lógica de negócios. De uma forma ou de outra, o controlador tomará uma decisão e precisará informar a exibição "é necessário".
Como a visão interpreta ou implementa isso realmente não importa do ponto de vista da lógica de negócios. Faça o seu campo obrigatório. Faça um pop-up ou atire em um canhão e diga ao usuário para entrar em y ou apenas seja teimoso e não deixe o pobre usuário fazer nada até que ele descubra isso.
E pense: tudo isso pode ter ocorrido porque o controlador tentou salvar e não colocou um valor para um campo obrigatório no banco de dados e estava respondendo apenas a um erro no banco de dados. Não importa no que diz respeito à vista.
Algo como um valor obrigatório ou limitado para uma entrada pode ser tratado em muitos lugares. Se você "apenas" o abordar na visualização, muitos desenvolvedores verão isso como um problema quando houver várias interfaces com o usuário. É por isso que a lógica de negócios pode ser criada e testada sem muito da interface do usuário ou mesmo do banco de dados. Você nem precisa ter um site.
fonte