APLICATIVOS DE LINGUAGEM DE PROGRAMAÇÃO ORIENTADA A OBJETOS (ALPOO) PADRÃO MVC (Model-View-Controller) Prof. Msc. Vladimir Camelo O padrão arquitetural MVC (Model-View-Controller) foi criado no contexto da linguagem Smalltalk com o objetivo de desacoplar a interface gráfica de uma aplicação do código que realmente realiza o trabalho. Causou um forte impacto na maneira com que o software era construído, dividindo a aplicação em três partes distintas: modelo, visão e controle. É aplicável a qualquer linguagem orientada a objetos. Desacopla visões (interface) da aplicação propriamente dita, utilizando para isso o padrão de projeto Observer. Desacopla cada uma das três partes de forma que as mudanças em uma delas seja automaticamente propagada para as outras, mantendo a consistência global entre todas as partes. Além do padrão Observer, o MVC pode ser modelado com o uso de vários padrões de projeto como: Composite, Strategy e FactoryMethod. No padrão MVC, o fluxo da aplicação é mediado por um controlador central (Controller). O controlador delega requisições para tratadores apropriados que estão localizados no modelo (Model), que representa a lógica de negócio e o estado da aplicação. A requisição então é respondida, através do controlador e apresentada na visão (View) da maneira adequada. 1. MODELO (Model) O modelo (model) representa os dados ou a camada de acesso a estes. Também representa as regras e lógicas de negócio, bem como mantém o estado da aplicação. No MVC o modelo é o código que carrega alguma tarefa. Ele deve ser desenvolvido sem nenhuma preocupação em como ele será apresentado ao usuário. Ele também tem uma interface puramente funcional, significando que tem um conjunto de métodos públicos que podem ser acessados para atingir suas funcionalidades. Alguns métodos servem para consultas que permitem que o usuário obtenha informações a respeito do estado atual do modelo. Os outros são métodos modificadores que permitem que o estado seja modificado. O modelo deve poder registrar visões e notificá-las quando um de seus métodos causa uma mudança no estado.
2. VISÃO (View) A camada de apresentação ou visão (view) provê componentes de interface gráfica para que o usuário seja capaz de modificar o modelo. Recebe os resultados do modelo e especifica como estes resultados serão projetados para o usuário. É responsabilidade das visões manter a consistência em sua apresentação quando o modelo muda. Um modelo em MVC pode ter várias visões. Exemplos: linhas e colunas de uma planilha e um gráfico de alguma coluna da mesma planilha. 3. CONTROLADORES (Controller) Os controladores (controllers) traduzem interações com as visões nas ações a serem executadas pelo modelo. Baseado nas interações do usuário e no resultado das ações do modelo, o controlador responde selecionando uma visão apropriada. As visões em MVC s são associadas diretamente aos controladores que são responsáveis por atualizar o modelo quando um usuário interage com uma visão. O controlador invoca métodos que modificam o modelo, mantendo-o sempre atualizado. 4. MVC COM Java Swing Primeira parte a escrever: o modelo. O modelo deve estender da classe Java.util.Observable que permitirá que as visões sejam notificadas a respeito de mudanças no modelo. Pode-se então escrever o código funcional do modelo, provendo métodos para a obtenção de informações do seu estado atual e para a atualização deste mesmo estado. O código dos métodos de atualização do modelo deve conter duas chamadas a médodos herdados da classe Observable: setchanged(true) e notifyobservers(). O primeiro método modifica o estado do modelo para modificado e o segundo serve para informar os observadores (no caso, as visões registradas) a respeito deste fato (lightwieghtnotification). Existe ainda uma outra versão do método notifyobservers (Object), a partir do qual é possível passar informações adicionais (statefulnotification). A partir daí podem ser criadas várias visões. Cada visão deve implementar a interface Java.util.Observer e consequentemente o método update(). O Object recebido no segundo parâmetro pode ser utilizado para receber informações adicionais. As visões devem implementar o método update() de forma que este consulte o modelo (no caso o objeto Observable t ) buscando mudanças que tenham ocorrido (ou
atualizando o modelo) e então faça as atualizações apropriadas em si mesmo. As visões devem registrar-se junto ao modelo que desejam observar através do método addobserver(). A razão pela qual o modelo deve estender a classe Observable é que a mesma provê toda a infraestrutura de registro/notificação necessária para implementar o MVC. 5. EXEMPLO Pacote model : contém a classe TemperaturaModel. Classe TemperaturaModel: package model; classe externa responsável pelas regras de negócio relacionadas às conversões da temperatura. Essa classe estende a classe Observable public class TemperaturaModel extends java.util.observable { //atributo privado private double temperaturaf = 32.0; //método para consulta da temperatura farenheit public double gettemperaturaf() { return temperaturaf; //método para atualização da temperatura farenheit public void settemperaturaf(double temperaturaf) { this.temperaturaf = temperaturaf; setchanged(); notifyobservers(); //método para alteração e consulta da temperatura celcius public double gettemperaturac() { return Math.round((temperaturaF - 32.0)*5.0/9.0); //método para alteração da temperatura farenheit public void settemperaturac(double temperaturac) { temperaturaf = Math.round(temperaturaC*9.0/5.0 + 32.0); setchanged(); notifyobservers(); Pacote view : contém as classes TemperaturaView, CelsiusView e FarenheitView. Classe TemperaturaView: package view; //importação de classes e interfaces import java.awt.*; import java.awt.event.*; classe abstrata para construção da interface gráfica e tratamento de eventos. Essa classe implementa a interface Observer abstract class TemperaturaView implements java.util.observer { //atributos da classe TemperaturaView private String label; private TemperaturaModel model; private Frame temperaturaframe; private TextField display = new TextField(); private Button upbutton = new Button("Acima"); private Button downbutton = new Button("Abaixo"); contrutor alternativo da classe TemperaturaView. criação e visualização da interface gráfica.
TemperaturaView(String label, TemperaturaModel model, int h, int v) { this.label = label; this.model = model; temperaturaframe = new Frame(label); temperaturaframe.add("north", new Label(label)); temperaturaframe.add("center", display); Panel buttons = new Panel(); buttons.add(upbutton); buttons.add(downbutton); temperaturaframe.add("south", buttons); temperaturaframe.addwindowlistener(new CloseListener()); model.addobserver(this); //conexão de View para Model temperaturaframe.setsize(300,120); temperaturaframe.setlocation(h,v); temperaturaframe.setvisible(true); //método para atualizar o campo texto public void setdisplay(string s){ display.settext(s); //método para capturar informação do campo texto public double getdisplay() { double resultado = 0.0; try { return Double.valueOf(display.getText()).doubleValue(); catch(numberformatexception e){ return resultado; //métodos tratadores para o evento de ação sobre os botões public void adddisplaylistener(actionlistener a){display.addactionlistener(a); public void adduplistener(actionlistener a){upbutton.addactionlistener(a); public void adddownlistener(actionlistener a){downbutton.addactionlistener(a); //método para retornar o model atual protected TemperaturaModel model(){return model; //classe interna para fechar as janelas public static class CloseListener extends WindowAdapter { public void windowclosing(windowevent e) { e.getwindow().setvisible(false); System.exit(0); Classe CelciusView: package view; //importanção de classes e interfaces import java.util.observable; import java.awt.event.*; classe externa para tratamento da temperatura em Celcius. Essa classe estende a classe TemperaturaView public class CelciusView extends TemperaturaView { //construtor alternativo para a classe CelciusView public CelciusView(TemperaturaModel model, int h, int v) { super("temperatura Celcius", model, h, v); setdisplay("" + model.gettemperaturac()); adduplistener(new UpListener()); adddownlistener(new DownListener()); adddisplaylistener(new DisplayListener()); //método para atualizar a temperatura em celcius public void update(observable t, Object o) {//chamada ao model setdisplay("" + model().gettemperaturac()); //Classes internas para tratamento do evento de ação sobre a temperatura celcius class UpListener implements ActionListener {
model().settemperaturac(model().gettemperaturac() + 1.0); class DownListener implements ActionListener { public void actionperformed(actionevent e) { model().settemperaturac(model().gettemperaturac() - 1.0); class DisplayListener implements ActionListener { double value = getdisplay(); model().settemperaturac(value); Classe FarenheitView: package view; //importanção de classes e interfaces import java.util.observable; import java.awt.event.*; classe externa para tratamento da temperatura em Farenheit. Essa classe estende a classe TemperaturaView public class FarenheitView extends TemperaturaView { //construtor alternativo para a classe FarenheitView public FarenheitView(TemperaturaModel model, int h, int v) { super("temperatura Farenheit", model, h, v); setdisplay("" + model.gettemperaturaf()); adduplistener(new UpListener()); adddownlistener(new DownListener()); adddisplaylistener(new DisplayListener()); //método para atualizar a temperatura em farenheit public void update(observable t, Object o) {//chamada ao model setdisplay("" + model().gettemperaturaf()); class UpListener implements ActionListener { model().settemperaturaf(model().gettemperaturaf() + 1.0); //Classes internas para tratamento do evento de ação sobre a temperatura farenheit class DownListener implements ActionListener { model().settemperaturaf(model().gettemperaturaf() - 1.0); class DisplayListener implements ActionListener { double value = getdisplay(); model().settemperaturaf(value); Pacote controller : contém a classe MVCConversaoTemperatura. Classe MVCConversaoTemperatura: package controller; //importação de classes e interfaces import view.farenheitview; import view.celciusview; //classe externa para controle da conversão de temperatura public class MVCConversaoTemperatura { //método principal
public static void main(string[] args) { //criação do objeto temperatura - instância da classe TemperaturaModel TemperaturaModel temperatura = new TemperaturaModel(); //objeto anônimo - instância da classe FarenheitView new FarenheitView(temperatura, 550, 200); //objeto anônimo - instância da classe CelciusView new CelciusView(temperatura, 550,350); BIBLIOGRAFIA BÁSICA Santos, Rui R. dos, Programando em Java 2 Teoria e Aplicações, Rio de Janeiro, Axcel books, 1ª edição, 2004. BIBLIOGRAFIA COMPLEMENTAR Morgan, Michael, Java 2, para programadores profissionais, Axcel books, 1ª edição, 2004. Deitel, H.M., Java, como Programar, São Paulo, Pearson, 1º reimpressão, 2006. Bauer, C., King, G., Java Persistence com Hibernate, Rio de Janeiro, Editora Ciência Moderna, 2007. BIBLIOGRAFIA SUGERIDA Moreira Neto, Oziel, Entendendo e dominando o Java para Internet São Paulo, Digerati Books, 2006.