Série DesignPattern:Bridge

Olá Pessoal,

No post de hoje vamos conhecer o padrão Bridge. Não é muito difícil surgir a necessidade do uso deste padrão. No exemplo de hoje você vai ver o motivo. Apesar de que você pode pensar: “hm, eu já implementei ele, mas nem fazia ideia”. Sim, isso é comum mesmo. Mas revise e veja se fez orientado à interfaces, pois é ai que está o pulo do gato.

Let’s go…

Bridge
A definição dele é bem curta veja:

“Separa a abstracao da representação de forma que ambos possam variar e produzir tipos de objetos diferentes”.

O que isso quer dizer?

Vamos ver de forma prática e com um exemplo do dia-dia. É comum em uma aplicação precisar gerar arquivos em formatos diferentes, certo? Se você desenvolve apenas focado nos formatos suportados atualmente terá um problema futuramente, caso surja a necessidade de suportar novos formatos. Vamos dizer que hoje sua aplicação gere arquivos apenas no formato .txt e .pdf., mas amanhã é necessário gerar arquivos no formato .doc e .xls. A forma que você implementa essa geração de arquivos vai dizer se isso custará muito ou não para o seu projeto. É preciso separar a abstração da representação (arquivo) com as formas que ele pode ser produzido. Independente do formato escolhido ele não deixa de ser um arquivo, o que varia ou muda é o tipo do arquivo. Captou a definição do Bridge?

Desenvolvimento
Vamos agora colocar mão na massa para ficar mais divertido e entender de fato o padrão Bridge. No projeto de hoje vamos poder gerar arquivos em diversos formatos. Nada de especial ai, porém tudo começa a ficar interessante se amanhã minha aplicação precisar suportar um formato especifico e ai que terei o “pulo do gato” ou não.

Passo 1
Crie um projeto conforme o meu a seguir:

Passo 2
Vamos pensar nos perguntando, certo?
O que eu quero?
R: Poder gerar um arquivo
Para quais formatos?
R: Os disponíveis na aplicação

Para a primeira pergunta vamos criar uma interface. O motivo é que nem tudo no sistema gera um arquivo, apenas em classes especificas de negócios fazem sentido gerar arquivos, como por exemplo:
Gerar um recibo para o cliente (classe recibo);
Gerar um arquivo com as despesas (classe despesas)
etc

Então as classes que precisam gerar um arquivo tem que implementar a interface, informar os dados que serão gerados e o tipo de arquivo desejado.

package br.com.camilolopes.bridge.interfaces;
/*
 * sempre que precisar gerar um arquivo
 * temos que implementar essa interface
 * e dizer o que teremos nesse arquivo
 */
public interface Arquivo {
    void geraArquivo();
}

Passo 2
Antes de definirmos quais classes da nossa aplicação são capazes de gerar arquivos, vamos criar o nosso gerador de arquivos, que na verdade será o Bridge na aplicação. Ele não passa de uma interface que será implementada pelos formatos suportados.

package br.com.camilolopes.bridge.interfaces;
/*
 * essa interface serão implementadas pelo
 * tipos de arquivos suportados a serem gerados
 * txt,pdf,zip,doc etc
 */
public interface GeradorDeArquivo {
    void criarArquivo(String dados);
}

Passo 3
Agora vamos dizer quais os formatos suportados. Aqui está o “pulo do gato”, se precisar adicionar um novo formato é só criar uma classe para o formato desejado e implementar a interface GeradorDeArquivo. Essa é a regra. E assim, todas as classes (recibo, desespas etc) podem gerar arquivos no novo formato disponível.

package br.com.camilolopes.bridge.classes;

import java.io.FileNotFoundException;
import java.io.PrintStream;

import br.com.camilolopes.bridge.interfaces.GeradorDeArquivo;
/*
 * classe que gera arquivo txt
 */
public class GeradorArquivoTxt implements GeradorDeArquivo {

    @Override
    public void criarArquivo(String dados) {
        try{
            PrintStream arquivo = new PrintStream(“arquivo.txt”);
            arquivo.println(dados);
            arquivo.close();
            System.out.println(“Arquivo gerado com sucesso”);
        }catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }
}

Passo 4
Agora a classe que pode gerar arquivo (Recibo, Despesas etc). Nela delegamos a criação do arquivo para o Bridge e ele se encarrega de gerar o arquivo com o tipo que passamos.

package br.com.camilolopes.classes;

import br.com.camilolopes.bridge.interfaces.Arquivo;
import br.com.camilolopes.bridge.interfaces.GeradorDeArquivo;
/*
 * classe que tem os dados que serão
 * gerados os arquivos
 * ela delega a geração do arquivo para um especialista no assunto
 */
public class Recibo implements Arquivo {
    private String emissor;
    private String favorecido;
    private double valor;
    /*como sempre orientado a interfaces
     * assim deixamos a chamada com base no tipo
     * passado
     */
    private GeradorDeArquivo geradorDeArquivo;

    //para gerar o recibo o usuario é obrigado informar o tipo desejado
    public Recibo(String emissor, String favorecido, double valor,GeradorDeArquivo tipoDoArquivo) {
        super();
        this.emissor = emissor;
        this.favorecido = favorecido;
        this.valor = valor;
        geradorDeArquivo = tipoDoArquivo;
    }

    @Override
    public void geraArquivo()  {
        StringBuilder dados = new StringBuilder();
            dados.append(“Recibo: “);
            dados.append(“\n”);
            dados.append(“Empresa: ” + this.emissor);
            dados.append(“\n”);
            dados.append(“Cliente: ” + this.favorecido);
            dados.append(“\n”);
            dados.append(“Valor: “+ this.valor);
            //informando os dados que serão gerados
            this.geradorDeArquivo.criarArquivo(dados.toString());
    }
}

Observe que é obrigado ao usuário quando for gerar um arquivo, além das informações, é preciso dizer o tipo do arquivo que ele deseja.

Passo 5
Vamos testar a nossa aplicação. Criamos uma classe com o método main que informa os dados a serem gerados e o tipo de arquivo desejado e em seguida veremos se o arquivo foi gerado e se a informação foi gravada de fato.

package br.com.camilolopes.main;

import br.com.camilolopes.bridge.classes.GeradorArquivoTxt;
import br.com.camilolopes.classes.Recibo;

public class TesteRecibo {

    public static void main(String[] args) {
    GeradorArquivoTxt arquivoTxt = new GeradorArquivoTxt();
    Recibo reciboAbril = new Recibo(“XX”, “Camilo Lopes”, 50.00, arquivoTxt);
        reciboAbril.geraArquivo();
    }
}

Conclusão
Observe que seu código ficou muito melhor estruturado e com fácil manutenção.

Git Hub 

Os projetos encontram-se no Github:

https://camilolopes@github.com/camilolopes/workspacedesignpattern.git 

Vou ficando por aqui e espero que tenham gostado do post de hoje.
Abraços, see ya!!

Um comentário em “Série DesignPattern:Bridge”

Deixe um comentário

O seu endereço de e-mail não será publicado.