Vous êtes sur la page 1sur 13

C

nfraria do Java

Grupo de Estudos de Linguagem Java dos Cursos de Informtica da Universidade Luterna do Brasil Campus Canoas

INTRODUO AO USO DE PADRES DE PROJETO


Karen Selbach Borges <kborges@ulbra.tche.br> Sandro Rogrio da Silva <sandroerita@pop.com.br> 10 de setembro de 2005

RESUMO
Este artigo apresenta uma introduo ao uso de padres no desenvolvimento de sistemas orientados a objetos. Dentre os 23 padres de projeto propostos pelo GoF, sero abordados os seguintes: Facade, Singleton, Factory, Template e Iterator. Alm destes sero apresentados os padres DAO e DTO do J2EE.

1 INTRODUO
Pontos chave da orientao a objetos como o reuso, o desacoplamento e a coeso do software podem ser incrementados com o uso de padres (design patterns). O reuso refere-se a criao de classes que possam ser utilizadas em diferentes projetos, sem a necessidades de adaptao. Para que isso seja possvel necessrio que as classes estejam desacopladas, ou seja, que no exista dependncia entre elas, e que o nvel de coeso seja alto, com todas as funes trabalhando no sentido de uma responsabilidade comum. Segundo Gamma, os padres de projeto so descries de objetos que se comunicam e classes que so customizadas para resolver um problema genrico de design em um contexto especfico". Dessa forma podemos considerar um padro como a descrio de uma soluo genrica para um determinado tipo de problema. O uso de padres propicia ao desenvolvedor uma melhor compreenso a respeito da arquitetura de frameworks, prov uma soluo de qualidade para determinados problemas e cria um vocabulrio comum capaz de expressar as solues em alto nvel de abstrao. Alm disso, ao utilizar padres se estar contribuindo para a melhoria da qualidade do software, pois as solues indicadas, por serem fruto do conhecimento e experincia de outros desenvolvedores, j foram devidamente testadas e documentadas. O estudo dos padres de projeto pressupe uma base mnima de conhecimentos sobre anlise e design orientado a objetos. recomendvel, tambm, alguma experincia com modelagem UML e programao com uma linguagem orientada a objetos (Java, C++, C#, etc). A seo 2 apresenta uma breve fundamentao terica a respeito dos padres de projeto, descrevendo a classificao dos padres segundo suas intenes. Em seguida, a seo 3 dedicada uma anlise dos padres Facade, Singleton, Factory, Template, Iterator. A seo 4 far uma introduo aos padres J2EE DAO e DTO. A seo 5 apresenta as concluses deste trabalho e, por fim, so apresentadas as referncias bibliogrficas.

2 PADRES DE PROJETO
Segundo Metsker (2004), Christopher Alexander foi um dos primeiros escritores a encapsular as melhores prticas de um ofcio por meio da documentao de seus padres. Seu trabalho est relacionado arquitetura de prdios, mas influenciou fortemente a comunidade de software, pois mostrou-se como uma excelente forma de captar e transmitir os conhecimentos a respeito de um ofcio. 1

nfraria do Java

Grupo de Estudos de Linguagem Java dos Cursos de Informtica da Universidade Luterna do Brasil Campus Canoas

A partir disso, foram criados diversos livros que documentam padres de desenvolvimento de software atravs do registro das melhores prticas para a anlise e projeto de software. Entre as diversas obras existentes, destaca-se o livro Design Patterns, elaborado por Gamma, Helm, Johnson e Vlissides, conhecidos como GoF ou Gang of Four. Esta obra definiu uma estrutura para catalogar e descrever padres de projeto, catalogou 23 padres e determinou estratgias e enfoques orientados a objetos baseados nesses padres. Os 23 padres catalogados, foram classificados de duas formas: Por propsito: criao de classes e objetos, alterao da estrutura de um programa, controle do seu comportamento. Por escopo: classe ou objeto Entretanto, este artigo se baseia na estrutura de catalogao de padres proposta por Metsker (2004), que classifica os padres em cinco grupos, por inteno, ou seja, conforme o problema a ser solucionado.

2.1 Tipos de Padres Segundo Suas Intenes


Optamos por seguir a estrutura proposta por Metsker, pelo fato de sua obra estar adequada linguagem Java. Os cinco grupos e seus respectivos padres podem ser visualizados a partir da figura abaixo :

Figura 1 Padres de Projeto segundo suas intenes (ROCHA, 2005)

Interfaces: padres que orientam a criao e utilizao de interfaces. Estas podem assumir duas conotaes: 1) como contratos que determinam o que a classe que implementam uma dada interface poder fazer ou 2) como forma de interao com um sistema. Responsabilidade: padres que orientam a distribuio de responsabilidades entre as classes. As responsabilidades so determinadas, nvel de implementao, atravs dos mtodos das classes e do uso de modificadores de acesso. Construo: padres que orientam a criao e utilizao de construtores. Estes so mtodos especiais que governam a instanciao da classes, ou seja, a criao dos objetos. Operaes: padres que orientam o desenvolvimento de mtodos. Estes constituem a implementao de uma operao, ou seja, a especificao de um servio que pode ser solicitado de uma instncia de uma classe. Extenses: padres que orientam a aplicao do conceito de herana. Este permite que novas classes sejam criadas como extenses de classes existentes, acrescentando novas propriedades e/ou novas responsabilidades. Para cada uma das categorias acima descritas, apresentaremos um padro atravs dos seguintes elementos: Objetivo: qual a finalidade do padro em questo.

nfraria do Java

Grupo de Estudos de Linguagem Java dos Cursos de Informtica da Universidade Luterna do Brasil Campus Canoas

Quando usar: descrio de situaes que podem tirar proveito do uso do padro em questo. Exemplo: de modelagem e/ou cdigo fonte que aplique o padro.

3 DESCRIO DOS PADRES


3.1 Faade
Visa: oferecer uma interface nica de nvel mais elevado para um conjunto de interfaces de um subsistema Quando usar: simplificar o uso de uma coleo de objetos Exemplo: o padro faade aplicado no exemplo a seguir com o intuito de fornecer um meio de interao com um sistema complexo. Ao invs de interagirmos diretamente com as classes Water, TeaBag e TeaCup, a interao ser feita mediante uma classe (FacadeTeaMaker) que representa uma interface de acesso.

FacadeTeaMaker

Water

TeaBag

TeaCup
Subsistema

Figura 2 Exemplo do padro Faade


public class FacadeTeaMaker { boolean teaBagIsSteeped; public FacadeTeaMaker(){ System.out.println("FacadeTeaMaker vai preparar uma deliciosa xicara de cha para voce ..."); } public TeaCup makeACup() { TeaCup cup = new TeaCup(); TeaBag teaBag = new TeaBag(); Water water = new Water(); cup.addTeaBag(teaBag); water.boilWater(); cup.addWater(water); cup.steepTeaBag(); return cup; }

public class TeaBag { public TeaBag() { System.out.println("aguarde pelo adoravel cha !"); } }

nfraria do Java

Grupo de Estudos de Linguagem Java dos Cursos de Informtica da Universidade Luterna do Brasil Campus Canoas

public class TeaCup { boolean teaBagIsSteeped; Water water; TeaBag teaBag; public TeaCup() { setTeaBagIsSteeped(false); System.out.println("aguarde pelo delicioso cha !"); } public void setTeaBagIsSteeped(boolean isTeaBagSteeped) { teaBagIsSteeped = isTeaBagSteeped; } public boolean getTeaBagIsSteeped() { return teaBagIsSteeped; } public void addTeaBag(TeaBag teaBagIn) { teaBag = teaBagIn; System.out.println("o saquinho de cha esta na xicara"); } public void addWater(Water waterIn) { water = waterIn; System.out.println("a agua esta na xicara"); } public void steepTeaBag() { if ( (teaBag != null) && ((water != null) && (water.getWaterIsBoiling())) ) { System.out.println("o cha esta pronto e esperando !"); setTeaBagIsSteeped(true); } else { System.out.println("o cha ainda nao esta pronto"); setTeaBagIsSteeped(false); } } public String toString() { if (this.getTeaBagIsSteeped()) { return ("Uma deliciosa xicara de cha !"); } else { String tempString = new String("Uma xicara com "); if (water != null) { if (water.getWaterIsBoiling()) { tempString = (tempString + "agua quente "); } else { tempString = (tempString + "agua fria "); } } else { tempString = (tempString + "sem agua "); } if (teaBag != null) { tempString = (tempString + "agua e saquinho de cha"); } else { tempString = (tempString + "agua sem saquinho de cha"); } return tempString; } } }

nfraria do Java

Grupo de Estudos de Linguagem Java dos Cursos de Informtica da Universidade Luterna do Brasil Campus Canoas

public class Water { boolean waterIsBoiling; public Water() { setWaterIsBoiling(false); System.out.println("aguarde pelo maravilhoso cha !"); } public void boilWater() { setWaterIsBoiling(true); System.out.println("a agua esta quente"); } public void setWaterIsBoiling(boolean isWaterBoiling) { waterIsBoiling = isWaterBoiling; } public boolean getWaterIsBoiling() { return waterIsBoiling; } }

public class TestaFacade { public static void main(String[] args) { FacadeTeaMaker cupMaker = new FacadeTeaMaker(); TeaCup teaCup = cupMaker.makeACup(); System.out.println(teaCup); } }

Figura 3 Padro Faade : exemplo de cdigo (adaptado de FluffyCat.com)

3.2 Singleton
Visa : garantir que uma classe s tenha uma nica instncia, e prover um ponto de acesso global a ela. Quando usar: quando apenas uma instncia for permitida Exemplo: um exemplo tpico de uso do padro Singleton na criao das classes que provm acesso a banco de dados. Como a classe que estabelece a conexo provavelmente tenha que ser utilizada em diversas partes do projeto necessrio garantir que sempre estar sendo utilizada a mesma conexo.

Figura 4 Esquema de implementao do padro Singleton (ROCHA, 2005)

nfraria do Java

Grupo de Estudos de Linguagem Java dos Cursos de Informtica da Universidade Luterna do Brasil Campus Canoas

import javax.swing.*; import java.sql.*; public class DBConnection { //Atributos para manipulao do BD private static final String DRIVER = "sun.jdbc.odbc.JdbcOdbcDriver"; private static final String URL = "jdbc:odbc:Contatos"; private static Connection conexao = null; public static Connection getConnection(String user, String password) throws ClassNotFoundException, SQLException { if( conexao == null ) { new DBConnection(user, password); } return conexao; } private DBConnection(String user, String password) throws ClassNotFoundException, SQLException { Class.forName(DRIVER); conexao = DriverManager.getConnection(URL, user, password); } public static void closeConnection()throws ClassNotFoundException, SQLException { if (conexao!=null) { conexao.close(); conexao=null; } }

Figura 5 Exemplo de implementao do padro Singleton. Adaptado de (JANDL, 2004)

3.3 Factory
Visa: definir uma interface para criar um objeto, mas deixar que subclasses decidam que classe instanciar. Quando usar: sempre que desejarmos oferecer um servio de criao de objetos quando o conjunto de classes concretas deva ser modificado com a adio de novas classes. Exemplo: a figura 7 apresenta um exemplo de cdigo combinando os padres Factory e Template. A classe ContatosFactory a aplicao do padro Factory, pois a responsvel pela definio de qual objeto ser instanciado (Pessoal ou Profissional)

Figura 6 - Esquema de implementao do padro Factory (JANDL, 2004)

3.4 Template
Visa: definir o esqueleto de um algoritmo dentro de uma operao, deixando alguns passos a serem preenchidos pelas subclasses Quando usar: quando a estrutura fixa de um algoritmo puder ser definida pela superclasse deixando certas partes para serem preenchidos por implementaes que podem variar. Exemplo: o cdigo a seguir combina os padres Factory e Template. Ao colocarmos os campos e operaes que so comuns a todas as classes em uma classe abstrata, 6

nfraria do Java

Grupo de Estudos de Linguagem Java dos Cursos de Informtica da Universidade Luterna do Brasil Campus Canoas

estamos aplicando o padro Template.


public class Endereco { private String logradouro; private String complemento; private int numero; private String cep; private String estado; private String cidade; //Construtor vazio public Endereco() { } public String getLogradouro() {return logradouro;} public void setLogradouro(String logradouro) {this.logradouro = logradouro;} public int getNumero() {return numero;} public void setNumero(int numero) {this.numero = numero;} public String getComplemento() {return complemento;} public void setComplemento(String complemento) {this.complemento = complemento;} public String getCep() {return cep;} public void setCep(String cep) {this.cep = cep;} public String getCidade() {return cidade;} public void setCidade(String cidade) {this.cidade = cidade;} public String getEstado() {return estado;} } public void setEstado(String estado) {this.estado = estado;}

public abstract class Contato{ protected int id; protected String nome; protected Endereco endereco; protected String telefone; protected String email; protected String homepage; public Contato() {} public int getId() {return id;} public void setId(int id) {this.id = id;} public java.lang.String getNome() {return nome;} public void setNome(java.lang.String nome) {this.nome = nome;} public Endereco getEndereco() {return endereco;} public void setEndereco(Endereco endereco) {this.endereco = endereco;} public java.lang.String getTelefone() {return telefone;} public void setTelefone(java.lang.String telefone) {this.telefone = telefone;} public String getEmail() {return email;} public void setEmail(String email) {this.email = email;} public String getHomepage() {return homepage;} } public void setHomepage(String homepage) {this.homepage = homepage;}

nfraria do Java

Grupo de Estudos de Linguagem Java dos Cursos de Informtica da Universidade Luterna do Brasil Campus Canoas

public class Pessoal extends Contato{ private String aniversario; private String celular; public Pessoal () { } public String getAniversario() {return aniversario;} public void setAniversario(String aniversario) {this.aniversario = aniversario;} public String getCelular() {return celular;} } public void setCelular(String celular) {this.celular = celular;}

public class Profissional extends Contato{ private String fax; public Profissional() { } public String getFax() {return fax;} } public void setFax(String fax) {this.fax = fax;}

public class ContatosFactory { public static final int PARTICULAR = 1; public static final int COMERCIAL = 2; public static Contato createContato(int tipoContato){ switch(tipoContato){ case PARTICULAR : return new Pessoal(); case COMERCIAL : return new Profissional(); } return null; }

import javax.swing.*; public class TestaFactory{ public static void main(String[] args){ String escolha = JOptionPane.showInputDialog (null, "Escolha: 1 - contato pessoal ou 2 contato particular"); int opcao = Integer.parseInt(escolha); if (opcao==1){ Contato c = ContatosFactory.createContato(ContatosFactory.PARTICULAR); c.setId(1); System.out.println("Criado contato particular = " + c.getId()); } else { Contato c = (Profissional)ContatosFactory.createContato(ContatosFactory.COMERCIAL); c.setId(2); System.out.println("Criado contato profissional = " + c.getId()); } System.exit(0);

Figura 7 Exemplo de aplicao dos padres Template e Factory

3.5 Iterator
Visa: prover uma maneira de acessar elementos de um objeto seqencialmente sem expor sua representao interna. Quando usar: para navegar em uma coleo elemento por elemento 8 agregado

nfraria do Java

Grupo de Estudos de Linguagem Java dos Cursos de Informtica da Universidade Luterna do Brasil Campus Canoas

Exemplo: as colees de objetos disponveis atravs do pacote java.util, tais como ArrayList e HashSet, implementam o padro Iterator, o qual permite que os objetos da coleo sejam visitados. De forma anlogo, a figura 8 apresenta a classe InnerIterator responsvel por percorrer os elementos contidos em um array, conforme determinado pela interface DvdListIterator.
public class TestaIterator { public static void main(String[] args) { DvdList fiveShakespeareMovies = new DvdList(); fiveShakespeareMovies.append("10 Things I Hate About You"); fiveShakespeareMovies.append("Shakespeare In Love"); fiveShakespeareMovies.append("Romeo and Juliet"); fiveShakespeareMovies.append("Hamlet"); fiveShakespeareMovies.append("Macbeth"); fiveShakespeareMovies.append("King Lear"); DvdListIterator fiveShakespeareIterator = fiveShakespeareMovies.createIterator(); while (!fiveShakespeareIterator.isDone()){ System.out.println(fiveShakespeareIterator.currentItem()); fiveShakespeareIterator.next(); } fiveShakespeareMovies.delete("Hamlet"); System.out.println(" "); fiveShakespeareIterator.first(); while (!fiveShakespeareIterator.isDone()){ System.out.println(fiveShakespeareIterator.currentItem()); fiveShakespeareIterator.next(); }

public interface DvdListIterator { public void first(); public void next(); public boolean isDone(); public String currentItem(); }

public class DvdList { private String[] titles; private int titleCount; private int arraySize; public DvdList(){ titles = new String[3]; titleCount = 0; arraySize = 3; } public int count() {return titleCount;} public void append(String titleIn) { if (titleCount >= arraySize){ String[] tempArray = new String[arraySize]; for (int i = 0; i < arraySize; i++) {tempArray[i] = titles[i];} titles = null; arraySize = arraySize + 3; titles = new String[arraySize]; for (int i = 0; i < (arraySize - 3); i++) {titles[i] = tempArray[i];} } titles[titleCount++] = titleIn; }

nfraria do Java

Grupo de Estudos de Linguagem Java dos Cursos de Informtica da Universidade Luterna do Brasil Campus Canoas

public void delete(String titleIn) { boolean found = false; for (int i = 0; i < (titleCount -1); i++) { if (found == false) { if (titles[i].equals(titleIn)) { found = true; titles[i] = titles[i + 1]; } } else { if (i < (titleCount -1)){titles[i] = titles[i + 1];} else {titles[i] = null;} } } if (found == true) {--titleCount;} } public DvdListIterator createIterator() {return new InnerIterator();} private class InnerIterator implements DvdListIterator { private int currentPosition = 0; private InnerIterator() {} public void first() {currentPosition = 0;} public void next() { if (currentPosition < (titleCount)){ ++currentPosition; } } public boolean isDone() { if (currentPosition >= (titleCount)) {return true;} else {return false;} } } public String currentItem() {return titles[currentPosition];}

Figura 8 Exemplo de aplicao do padro Iterator (adaptado de FluffyCat.com)

4 PADRES J2EE
4.1 4.1 Data Access Object
O pattern DAO implementa um objeto que responsvel por receber informao de um armazenamento persistente, onde quer que ele esteja. Isto abstrai a viso do dado usada por uma aplicao do layout da tabela, esquema XML ou arquivo em disco. Visa: oferecer uma nica camada de acesso a uma fonte de dados. Quando usar: sempre que precisar acessar dados perisitentes. Exemplo: Utilizar o padro DAO para persistir os dados, criando uma interface que contenha todos os mtodos que sero necessrios para persistir e recuperar objetos do banco de dados.

10

nfraria do Java

Grupo de Estudos de Linguagem Java dos Cursos de Informtica da Universidade Luterna do Brasil Campus Canoas

Figura 9 Diagrama de classes representando o padro DAO (SUN, 2005)

Onde : BusinessObject: representa a classe que representa uma entidade cujos dados sero persistidos. DataAccessObject: representa a classe atravs da qual feita toda a manipulao da base de dados. DataSource: representa as classes de conexo com o banco de dados. TransferObject: representa a entidade cujos dados esto armazenados no banco de dados. Corresponde a implementao do padro DTO, que ser analisado a seguir.

import java.sql.*; public interface DAOInterface{ public void armazenar(Object obj); public ResultSet consultar(String query); public void atualizar (Object obj); public void excluir (Object obj); } public class ContatoDAO implements DAOInterface{ public public public public public public final final final final final final static static static static static static int int int int int int NOME = 1; ENDERECO = 2; TELEFONE = 3; EMAIL = 4; HOMEPAGE = 5; ID = 8;

private static Connection conexao = DBConnection.getConnection(); public void armazenar (Object obj){ Contato contato = (Contato) obj; try { String query = "INSERT INTO TBCONTATOS VALUES(?, ?, ?, ?, ?)"; PreparedStatement ppst = conexao.prepareStatement(query); ppst.setString( NOME, contato.getNome() ); ppst.setString( ENDERECO, contato.getEndereco().toString() ); ppst.setString( TELEFONE, contato.getTelefone() ); ppst.setString( EMAIL, contato.getEmail()); ppst.setString( HOMEPAGE, contato.getHomepage()); int rs = ppst.executeUpdate(); if (rs==1) JOptionPane.showMessageDialog(null, "Registro Inserido Com Sucesso !", "Insero", JOptionPane.INFORMATION_MESSAGE); } catch (SQLException sqlex) { JOptionPane.showMessageDialog(null,"No possvel inserir !"); } }

11

nfraria do Java

Grupo de Estudos de Linguagem Java dos Cursos de Informtica da Universidade Luterna do Brasil Campus Canoas

public ResultSet consultar(String query){ // Implementa a seqncia de cdigo necessria para realizar um select } public void atualizar (Object obj){ // Implementa a seqncia de cdigo necessria para realizar um update } public void excluir (Object obj){ // Implementa a seqncia de cdigo necessria para realizar um delete } }

Figura 10 Exemplo de implementao do padro DAO

4.2 Data Transfer Object


DTOs, tambm conhecidos como VO (Value Object) ou TO (Transfer Object), trabalham coletando conjuntos de informaes relacionadas em um nico objeto. Sua funo Visa: transferncia de dados persistentes para a aplicao. Quando usar: agrupar dados obtidos a partir de diversas tabelas em um nico objeto e pass-lo para a cama de inteface do sistema. Exemplo de DTO: Com base no exemplo anterior criamos uma classe ContatoVO que possui apenas as informaes necessrias para serem apresentadas ao usurio.
public class ContatoVO{ private String nome; private Endereco endereco; private String telefone; public ContatoVO(){ }

// Implementao do padro Value Object public void setContatoVO(Contato c) { this.setNome(c.getNome()); this.setEndereco(c.getEndereco()); this.setTelefone(c.getTelefone()); } public ContatoVO getContatoVO(){return this;} public java.lang.String getNome() {return nome;} public void setNome(java.lang.String nome) {this.nome = nome;} public Endereco getEndereco() {return endereco;} public void setEndereco(Endereco endereco) {this.endereco = endereco;} public java.lang.String getTelefone() {return telefone;} public void setTelefone(java.lang.String telefone) {this.telefone = telefone;} public String toString(){ return ("\nNome = " + nome + "\nEndereco = " + endereco + "\nTelefone = " + telefone ); } }

Figura 11 Exemplo de implementao do padro DTO

12

nfraria do Java

Grupo de Estudos de Linguagem Java dos Cursos de Informtica da Universidade Luterna do Brasil Campus Canoas

5 CONCLUSO
Este artigo apresentou alguns padres de projeto, seus objetivos e exemplos de aplicao. Espera-se com isto despertar o interesse para o estudo desta rea, que tem se mostrado de fundamental importncia para o desenvolvimento de sistemas robustos e simples de serem mantidos.

REFERNCIAS
FluffyCat.com. Design Patterns in Java - Reference and Example Site. Disponvel em < http://www.fluffycat.com/java/patterns.html>. Acesso em set. 2005. JANDL, Peter. Padres de Projeto em Java. Revista Mundo Java, nro 6, pgs 17-23. 2004. METSKER, Steven John. Padres de Projeto em Java. Ed. Bookman. 2004. METSKER, Steven John. Design Patterns Java Workbook. Ed. Addison-Wesley, 2002 ROCHA, Helder. GoF Design Patterns em Java. Disponvel em < http://www.argonavis.com.br/cursos/java/j930>. Acesso em jul. 2005. SHALLOWAY, Alan; TROTT, James R. Explicando Padres de Projeto: Uma Nova Perspectiva em Projeto Orientado a Objeto. Ed. Bookman. 2004. SUN. Core J2EE Patterns - Data Access Object. Disponvel em <http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html>. Acesso em set.2005.

13

Vous aimerez peut-être aussi