Strategy com EJB [RESOLVIDO]

11 respostas
P

Pessoal, Boa Tarde !

Estou implementando uma nova funcionalidade, que basicamente consiste em ter várias plataformas que farão processamento.

A idéia é usar o padrão strategy juntamente com uma Factory…

A dúvida é… minha factory já retornar o EJB direto (ele implementará a interface e terá o método processaRegistro()) ou eu retorno uma classe de negócio q não é um EJB e ela irá implementar o método processaRegistro() e dentro dele ela chama o EJB…

Não sei quais os contras de usar essa abordagem com EJB… aceito sugestões para novas idéias…

Mais uma vez obrigado !

11 Respostas

V

Cara, uma factory eh um design pattern proposto para encapsular as dificuldades tecnicas de se instanciar um determinado objeto, portanto, sua factory nao deve retornar um EJB pois esses caras ja foram instanciados por um container, alem disso, no caso em que sua “strategy” for um EJB o seu container sera responsavel pelo gerenciamento desses objetos, bem como os lookups necessarios para recuperar tais beans. Note que o proposito de um container EJB eh admistrar as instancias dos objetos de negocios, e como seus “strategies” nao sao objetos de negocios (mas apenas um encapsulamento de um algoritmo) nao deve ser pensado com uma EJB.

abrsss

P

OK Vini… então a melhor abordagem seria retornar uma classe de negócio q não é um EJB e no método que processa eu chamaria o EJB em si…

por ex…

minha fabrica retorna um objeto que implementa um método de interface… esse método chama um ejb que faz o processamento…

FAria mas sentido ou dá na mesma??

obrigado

V

Cara, segue a minha ideia codificada.

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.teste.processador;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author lc28173
 */
interface ProcessadorArquivo {

    void processar(File arquivo);
}

class ProcessadorArquivoXML implements ProcessadorArquivo {

    @Override
    public void processar(File arquivo) {
        System.out.println("Processou o arquivo XML: "+arquivo.getName());
    }
}

class ProcessadorArquivoTXT implements ProcessadorArquivo {

    @Override
    public void processar(File arquivo) {
        System.out.println("Processou o arquivo TXT: "+arquivo.getName());
    }
}

class ProcessadorArquivoZIP implements ProcessadorArquivo {

    @Override
    public void processar(File arquivo) {
        System.out.println("Processou o arquivo ZIP: "+arquivo.getName());
    }
}

enum TipoArquivo {

    XML, TXT, ZIP;
}

class ProcessadorFactory {

    private ProcessadorFactory() {
    }

    //Aqui estamos utilizando reflection para evitar alguns IF´s ao instanciar um processador.
    public static ProcessadorArquivo getProcessador(TipoArquivo tipoArquivo) {
        try {
            return (ProcessadorArquivo) Class.forName("br.com.teste.processador.ProcessadorArquivo" + tipoArquivo).newInstance();
        } catch (Exception ex) {
            throw new IllegalArgumentException("Nao encontrou o processador: " + "ProcessadorArquivo" + tipoArquivo, ex);
        }

    }
}

class Main {

    public static void main(String[] asdf) {
        List<File> arquivos = gerarListaArquivos();
        ProcessadorArquivo processador = null;
        String extensao = null;
        for (File file : arquivos) {
            extensao = file.getName().split("\\.")[1].toUpperCase();
            processador = ProcessadorFactory.getProcessador(TipoArquivo.valueOf(extensao));
            //Polimorfismo na veia para tratar os arquivos sem ter que implementar um montao de IFs para determinar o tipo de arquivo.
            processador.processar(file);
        }

        
    }

    private static List<File> gerarListaArquivos() {
        List<File> lista = new ArrayList<File>();
        lista.add(new File("asdf.xml"));
        lista.add(new File("nada.xml"));
        lista.add(new File("wwwwww.xml"));
        lista.add(new File("teste.txt"));
        lista.add(new File("teste2.txt"));
        lista.add(new File("teste3.txt"));
        lista.add(new File("rrrr.zip"));
        lista.add(new File("rrrr2.zip"));
        lista.add(new File("rrrr3.zip"));
        return lista;
    }
}

Cada um de seus processadores podem consumir um EJB via injecao dependencia para consultar outro sistema, BD, etc.

abrasss

P

Legal Vini, agradeço muito pela ajuda… no final vc tocou no ponto principal de tudo isso…

Como estou em um sistema legado, não posso usar CDI…trazendo o meu caso para o seu exemplo, minhas classes que processam arquivos iriam chamar uma outra factory que retorna uma instancia do EJB e usaria esse EJB dentro dela…

ficaria mais ou menos assim:

class ProcessadorArquivoTXT implements ProcessadorArquivo {  
  
    @Override  
    public void processar(File arquivo) {  
       MeuEjb ejb =  Factory.getInstance().getProcessaArquivoBC();
       
      ejb.processarArquivoTxt();


    }  
}

Eu criaria um EJB para cada metodo de processamento para ser chamado dentro das classes processadoras… e cada um teria o seu DAO também…

Será que é por aí mesmo??

Obrigado !!

V

O que voce esta chamando de “factory de EJBs” eh na verdade um mecanismo de lookup pois os recursos (EJBs) ja existem e voce esta apenas recorrendo a eles, mas voce pode implementar essa metodologia, sim. Pode fazer uma injecao de dependencia atraves de um metodo set:

interface ProcessadorArquivo {  
  
    void processar(File arquivo);  
    void setEJB(EJB recurso); 
}

Isso eh muito comum.

abrs

P

Olá Vini,

Então, essa factory é uma classe que já existe no sistema… vc pega uma instancia dela com singleton e quando chama um método por exemplo
Factory.getInstance().getBusinessDevolucao, ela faz o lookup no meu ejb e te retorna a instancia dele…

O seu exemplo seria uma injeção de dependencia por setter, é isso? no caso eu teria q usar algum framework pra fazer isso certo ??

obrigado !!

R

Cara, só uma pergunta … você PRECISA ou QUER usar EJB ? Porque ao que me parece, você está morrendo de vontade de usar EJB e está uma oportunidade para tal.

Mas vamos lá. Se tudo o que as suas classes tem a fazer é processamento, puro e simples, a melhor coisa é usar POJOs mesmo. Só é interessanete usar EJBs quando:

  • você precisa demarcar transação
  • você precisa expor um serviço (RMI, SOAP, etc.)
  • você precisa acesssar o contexto do servidor de aplicação

Particularmente, eu somente usaria EJB’s como Facades, ou seja, classes que agrupam interfaces de serviços, ou seja, operações que por natureza são transacionais e/ou de “granularidade grossa”. Classes que não dependem de transações ou contextos, ou que executam tarefas de uma “granularidade fina” não pagam o custo de deixar o conteiner gerenciar seus objetos.

Outra dica: implemente sua solução, faça-a funcionar e somente então refatore para algum padrão conhecido.

V

rmendes08:
Cara, só uma pergunta … você PRECISA ou QUER usar EJB ? Porque ao que me parece, você está morrendo de vontade de usar EJB e está uma oportunidade para tal.

Mas vamos lá. Se tudo o que as suas classes tem a fazer é processamento, puro e simples, a melhor coisa é usar POJOs mesmo. Só é interessanete usar EJBs quando:

  • você precisa demarcar transação
  • você precisa expor um serviço (RMI, SOAP, etc.)
  • você precisa acesssar o contexto do servidor de aplicação

Particularmente, eu somente usaria EJB’s como Facades, ou seja, classes que agrupam interfaces de serviços, ou seja, operações que por natureza são transacionais e/ou de “granularidade grossa”. Classes que não dependem de transações ou contextos, ou que executam tarefas de uma “granularidade fina” não pagam o custo de deixar o conteiner gerenciar seus objetos.

Outra dica: implemente sua solução, faça-a funcionar e somente então refatore para algum padrão conhecido.

É isso ai!

P

rmendes08:
Cara, só uma pergunta … você PRECISA ou QUER usar EJB ? Porque ao que me parece, você está morrendo de vontade de usar EJB e está uma oportunidade para tal.

Caro rmendes08, não estou MORRENDO de vontade de usar EJBs, eu PRECISO USAR EJBs e o 2.1 ainda… tudo isso que vc disse eu já sei, e inclusive eu arrancaria um monte deles aqui… eu só estou tentando encaixá-los em um design melhor…

Mas de qualquer jeito obrigado.

V

Caso o topico esteja encerrado, favor incluir no titulo [RESOLVIDO].

ABRS

D

Vini Fernandes:
Caso o topico esteja encerrado, favor incluir no titulo [RESOLVIDO].

ABRS

Por isso parei aqui…
Inutilmente…

Mas, ja que perdi o tempo de vir até aqui,
parabens pela codificação.
Gostei da ideia de usar o tipo de arquivo para instanciar
a classe do tipo necessário :slight_smile:

muito bom.
Abraços

Criado 18 de setembro de 2012
Ultima resposta 20 de set. de 2012
Respostas 11
Participantes 4