No livro Utilizando UML e Padrões, Craig Larman fala sobre um outro tipo de controlador, que fica na camada de domínio ou modelo. É um controlador que possui conceitos de negócio, e pode coordenar diversas classes de negócio. Esse tipo de controlador pode representar um caso de uso ou o sistema como um todo.
Acho que a confusão se deve um pouco à existência de vários tipos de controladores.
Nesse mesmo livro (pág. 322 da 3a. edição), Craig Larman diz que no Processo Unificado e no método Objectory de Jacobson há três tipos de objetos:
objetos de fronteira - abstrações das interfaces (por exemplo, classes Swing).
objetos de entidade - objetos de domínio (negócio ou modelo) independentes da aplicação e geralmente persistentes.
objetos de controle - são tratadores de caso de uso - são os controladores que ficam na camada de domínio, de que falei.
[quote=al.barbosa]No livro Utilizando UML e Padrões, Craig Larman fala sobre um outro tipo de controlador, que fica na camada de domínio ou modelo. É um controlador que possui conceitos de negócio, e pode coordenar diversas classes de negócio. Esse tipo de controlador pode representar um caso de uso ou o sistema como um todo.
Acho que a confusão se deve um pouco à existência de vários tipos de controladores.[/quote]
Provavemente isso é uma tradução imprecisa para o padrão Mediator. A referência que você usou é em inglês?
[quote=ViniGodoy][quote=al.barbosa]No livro Utilizando UML e Padrões, Craig Larman fala sobre um outro tipo de controlador, que fica na camada de domínio ou modelo. É um controlador que possui conceitos de negócio, e pode coordenar diversas classes de negócio. Esse tipo de controlador pode representar um caso de uso ou o sistema como um todo.
Acho que a confusão se deve um pouco à existência de vários tipos de controladores.[/quote]
Provavemente isso é uma tradução imprecisa para o padrão Mediator. A referência que você usou é em inglês?[/quote]
Não, a referência é em Português. Na resposta anterior coloquei o link para a o livro on-line, é o Utilizando UML e Padrões do Craig Larman. Não é o padrão Mediator, da Gangue dos Quatro. O livro apresenta os padrões denominados GRASP (General Responsibility Assignment Software Patterns). São padrões e ao mesmo tempo princípios para atribuir responsabilidades. Alguns deles: Especialista na Informação, Criador, Acoplamento Baixo, Coesão Alta e Controlador. Além deles, o livro ensina alguns padrões da Gangue dos Quatro.
Cito abaixo um trecho do livro que fala sobre os padrões da Gangue dos Quatro:
[quote=Utilizando UML e Padrões - pág. 290]… durante a atividade de desenho (e codificação), aplicamos vários princípios de projeto OO, como GRASP e os padrões de projeto da Gangue dos Quatro (Gang-of-Four - GoF).
[/quote]
Cito abaixo uma explicação do livro sobre o GRASP:
Abaixo a definição do padrão Controlador no livro:
E abaixo a explicação do livro sobre a diferença entre o controlador GRASP e o controlador MVC:
Bom, esse trecho já diz tudo. Que o controller do MVC apenas “controla a interação e o fluxo de página da IU”.
É o que eu e o j0nny estavamos falando. E é por isso que ele quase some em desktop (esse controle é trivialmente feito pela linguagem).
Mas talvez daí suja tanta confusão sobre o papel do controller.
PS: Também gosto muito desse livro. Tenho impresso em casa, e já li de ponta-a-ponta.
Gostei muito desde tópico, e me deu a entender que eu estava pensando em MVC de forma errada. Tipo, utilizava o MODEL somente para a comunicação com o banco, e o CONTROLLER usava como a camada de negócios, que acredito que seja a entrada o processamento e saida para view.
Posso estar errado, trabalho com PHP e agora estou estagiando e aprendendo (também) J2EE para web.
Gostaria que alguem me desse um pequeno exemplo de aplicação, ou seja, como funcionaria se eu tivesse por exemplo uma tabela CLIENTES e quisesse mostrar dados do cliente, assim como cadastrar, alterar e excluir.
Posso esta pedindo muito, mas um pequena explicação irá me ajudar a compreender o que eu possa estar ou não fazendo de errado.
Atendendo ao pedido, e para ficar mais claro o padrão MVC, resolvi colocar um exemplo simples de CRUD para Web no padrão MVC.
Estou seguindo a abordagem sugerida no livro Core Servlets e Javaserver Pages, de Marty Hall e Larry Brown, capítulo 15: como integrar servlets e JSP: a arquitetura Modelo Visão Controlador (MVC). Abaixo um link para o livro on-line (este link está em Inglês, tem o livro à venda em Português).
A classe ServletCliente funciona como o controlador MVC.
Os JSP´s funcionam como a view.
Na parte do modelo, utilizo a classe RoteiroCliente. Nessa classe aplico o padrão Roteiro de Transação (Transaction Script) do livro Padrões de Arquitetura de Aplicações Corporativas, de Martin Fowler. Essa é a classe em que coloco as regras de negócio. Neste exemplo as únicas regras de negócio são: o cliente deve ter 18 anos de idade ou mais, e o seu nome não pode ser vazio. Cito abaixo a página 72 do livro do Martin Fowler, que fala sobre a possibilidade de usar Roteiros de Transação como modelo:
Poderia também utilizar uma classe de domínio como modelo - isso seria o padrão Modelo de Domínio citado acima (e o DDD - Domain-Driven Design). Porém o Martin Fowler recomenda utilizar um Mapeador de Dados (para o mapeamento objeto-relacional) ao utilizar um Modelo de Domínio mais rico, ou um Registro Ativo (padrão em que o modelo e o acesso a dados ficam na mesma classe) para domínios simples. Como eu não quis entrar na complexidade do mapeamento objeto-relacional neste exemplo, e queria separar o acesso a dados das regras de negócio, decidi utilizar o Roteiro de Transação.
A classe ClienteTO funciona como um Transfer Objetc, ou Objeto de Transferência de Dados. Esta classe serve apenas para transportar dados entre as camadas - não é propriamente uma classe de negócios.
E utilizo a classe ClienteDAO.java para interagir com o banco de dados. Ela é um Data Access Object. Para o exemplo funcionar, não coloquei um acesso real a banco de dados. Criei uma List na classe para armazenar os dados. Num caso real eu iria colocar o SQL nesta classe. Pode parecer que a classe ClienteDAO tem métodos muito parecidos com a classe RoteiroCliente. Isso acontece porque trata-se de um CRUD simples. A classe RoteiroCliente encapsula a regra de negócio, enquanto ClienteDAO encapsula o acesso a banco de dados. Num caso muito simples, é possível que sejam apenas uma classe - isso seria o padrão Registro Ativo, do livro Arquitetura de Aplicações Corporativas do Martin Fowler, pág. 165.
Segundo o Martin Fowler o valor do MVC está em duas separações:
1 - separar a apresentação do modelo (conforme trecho citado acima)
2 - separar a vista do controlador.
Cito abaixo um trecho em que ele fala sobre a segunda separação (pág. 317):
Por isso eu não acho muito útil o MVC para aplicações Java desktop na maioria dos casos. Porém acho importante a primeira separação: separar a apresentação do modelo - para esse tipo de aplicação.
private void incluir(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ClienteTO cliente = new ClienteTO();
try{
String nome = request.getParameter(“nome”);
int idade = parseIdade(request.getParameter(“idade”));
cliente = new ClienteTO(0, nome, idade );
roteiro.incluir(cliente);
listar(request,response);
}catch(Exception e){
request.setAttribute(“dado”, cliente);
request.setAttribute(“erro”, "Ocorreu o seguinte erro: " + e.getMessage());
despacha(request, response, “cliente.jsp”);
}
}
private void alterar(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ClienteTO cliente = new ClienteTO();
try{
int codigo = Integer.parseInt(request.getParameter(“codigo”));
String nome = request.getParameter(“nome”);
int idade = parseIdade(request.getParameter(“idade”));
cliente = new ClienteTO(codigo, nome, idade );
roteiro.alterar(cliente);
listar(request,response);
}catch(Exception e){
request.setAttribute(“dado”, cliente);
request.setAttribute(“erro”, "Ocorreu o seguinte erro: " + e.getMessage());
despacha(request, response, “cliente.jsp”);
}
}
private void excluir(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int codigo = Integer.parseInt(request.getParameter(“codigo”));
try{
roteiro.excluir(codigo);
listar(request,response);
}catch(Exception e){
request.setAttribute(“erro”, "Ocorreu o seguinte erro: " + e.getMessage());
List lista = roteiro.carregarTodos();
request.setAttribute(“lista”, lista);
despacha(request, response, “listaClientes.jsp”);
}
}
private int parseIdade(String idade) throws Exception{
try{
return Integer.parseInt(idade);
}catch(Exception e){
throw new Exception(“Campo idade deve ser um valor numerico”);
}
}
Data Access Object de Cliente
*/
public class ClienteDAO {
private List listaClientes = new ArrayList();
public ClienteDAO(){
listaClientes.add(new ClienteTO(1, “Francisco Paulo Souza”, 31));
listaClientes.add(new ClienteTO(2, “Maria Joana Souza”, 29));
listaClientes.add(new ClienteTO(1, “Paulo Franco Silva”, 32));
}
private int novoCodigo(){
int maior = 0;
for(ClienteTO c:listaClientes){
maior = c.getCodigo() > maior ? c.getCodigo() : maior;
}
return ++maior;
}
}[/code]
Anexei um diagrama ilustrando essa arquitetura. O diagrama é apenas para mostrar a estrutura de camadas, não corresponde exatamente aos pacotes java.
Fiz esse projeto no NetBeans. Anexei o projeto.
Concluo dizendo que esta é uma forma de estruturar a arquitetura do sistema. Há várias outras formas possíveis. A arquitetura do sistema tem que ser sempre pensada de acordo com as características do sistema. No livro do Martin Fowler há várias abordagens de camadas, e explicações sobre quando utilizar uma ou outra abordagem. A quem se interessar, coloco o link:
Recomendo fortemente tu dar uma estudada sobre DDD (domain driven design) de Eric Evans. Se possível compre o livro pois é muito bom.
Em termos de arquitetura de camadas essa “filosofia” define 4 camadas:
UI (interface com usuário)
Aplicação (controladores, frameworks, etc…)
Domínio (negócio/regras, entidades)
Infraestrutura (consumo de serviços de outros sistemas: banco de dados, email, webservices)
o enfoque está na camada de domínio, a qual representa os conceitos do problema, e deve ter o mínimo possível de dependência com outras tecnologias (frameworks, etc) pois no mundo real não existe tecnologia (enviar um email tem o conceito “enviar email” e não “m = new SimpleEmail(); m.set… m.send();”). No livro é descrito várias técnicas para isolamento do negócio, conceitos como VO, Repository, Services, Módulos, Fábricas, Agregadores… (Alguns do GoF com roupa nova )
Em comparação com o MVC eu vejo o DDD como uma evolução, em termos de conceito. Alguns podem falar que é igual ao MVC com a camada de infra.
Mas se estudar sobre, vai ver que é muito mais profundo, claro, específico e aplicável.
Quanto ao DAO, com uso de ORM (JPA, hibernate, etc…), dependendo da complexidade da aplicação eu vejo desnecessário, mas se for usar, use o conceito de Repository e coloque as implementações na camada de infra, pois o padrão DAO foi criado pra resolver problemas de suporte a multiplos bancos de dados na época que usavamos JDBC.
A vantagem que você verá de imediato é a facilidade de testar sua aplicação, manutenter e evoluir, e irá pensar primeiro no domínio do negócio e depois na solução técnica.
Pra mim também sempre foi na camada model , mas aonde eu trabalhava isso era feito na camada de controller em actions.
Agora mexo com EJB e não utilizo mais DAOs , pois entendo que eles são desnecessários.
O que utilizo são classes de serviços , interfaces que fornecem acesso aos EJBs que por sua vez sim fazem o trabalho de isolar realmente a lógica da aplicação das demais camadas.
No meu model só tem entidades que represetam tabelas do banco.
Acho que conceitualmente é muito organizado e faz divisão clara do MVC.
Como disseram não é errado dizer que é no model , porque no momento em que foi criado isso não era descrito.
Só tem três camadas então vai ser em uma delas MVC , sempre achei errado colocar no controller pq sempre tive a visão que essa camada era de gerenciamente e view de apresentação, então sempre pareceu errado colocar regra de negócios nelas.
[quote=fabioFx]Recomendo fortemente tu dar uma estudada sobre DDD (domain driven design) de Eric Evans. Se possível compre o livro pois é muito bom.
Em termos de arquitetura de camadas essa “filosofia” define 4 camadas:
UI (interface com usuário)
Aplicação (controladores, frameworks, etc…)
Domínio (negócio/regras, entidades)
Infraestrutura (consumo de serviços de outros sistemas: banco de dados, email, webservices)
o enfoque está na camada de domínio, a qual representa os conceitos do problema, e deve ter o mínimo possível de dependência com outras tecnologias (frameworks, etc) pois no mundo real não existe tecnologia (enviar um email tem o conceito “enviar email” e não “m = new SimpleEmail(); m.set… m.send();”). No livro é descrito várias técnicas para isolamento do negócio, conceitos como VO, Repository, Services, Módulos, Fábricas, Agregadores… (Alguns do GoF com roupa nova )
Em comparação com o MVC eu vejo o DDD como uma evolução, em termos de conceito. Alguns podem falar que é igual ao MVC com a camada de infra.
Mas se estudar sobre, vai ver que é muito mais profundo, claro, específico e aplicável.
Quanto ao DAO, com uso de ORM (JPA, hibernate, etc…), dependendo da complexidade da aplicação eu vejo desnecessário, mas se for usar, use o conceito de Repository e coloque as implementações na camada de infra, pois o padrão DAO foi criado pra resolver problemas de suporte a multiplos bancos de dados na época que usavamos JDBC.
A vantagem que você verá de imediato é a facilidade de testar sua aplicação, manutenter e evoluir, e irá pensar primeiro no domínio do negócio e depois na solução técnica.
[/quote]
Não confunda MVC com camadas, essa eh uma confusao comum. Mas elas nem passam perto de ser a mesma coisa. Por isso o DDD não é uma evolução do MVC, na verdade ele nada tem a ver com MVC, nem o conceito das camadas logicas (interface, negocios, acesso a dados) ou como na definicao do Evans (interface, aplicacao, negocios, infra) não tem nada a ver com o Model-View-Controller.
Model-View-Controller é um pattern criado para separar a interface com o usuario do resto da aplicacao. View é a interface, Controller uma fina camada separadora e Model é todo o resto incluindo as 387 possíveis camadas mais banco de dados sistema de arquivo, acesso a web service e afins.
[quote=Rodrigo Sasaki]Pra mim o Model era a parte que lidava só com dados, sem regra nenhuma de negócio aplicada (Entidades e DAOs, basicamente).
[/quote]
Model -> É composta pelas classes Action, Service e DAO. Cada entidade deve possuir esse trio.
As classes Actions são responsáveis pelo recebimento dos parametros originados na view e pela obtensão da conexao… e as envia à classe Service
As classes Services são as que guardam todas as regras de negócios. Solicitam às classes DAO as listas de dados ou inclusões. exclusões e updates…
As classes DAO fazem somente a parte de persistência, gerando listas de dados ou fazendo inclusões e atualizações…
Uma classe Action conversa somente com a classe Service que conversa somente com a classe DAO
Action <–> Service <–> DAO
obs: Esse formato facilita bastante o uso de transactions, uma vez que a conexão criada na action é enviada por referência a todos os métodos que farão parte da regra de negócios.
View -> É a camada de interface ao usuário
Controller -> Controla as requisições fazendo a comunicação entre a View e a classe Action