Sugestão de Implementação com Design Parttner

21/02/2011

0

Caros colegas,
Sempre que possível gosto de utilizar algum design partner em meus códigos.
Tenho um em particular que fico em dúvida sobre a real necessidade e sobre qual usar.

Os requisitos são os seguintes:

1) Recebo em um método parâmetros provenientes de servlet, que chega como string (obviamente).
2) Essa string possui 2 parâmetros que devo decompor (através de splits).
3) O primeiro parâmetro a ser decomposto dessa string é uma ação, como por exemplo: incluir_ids ou excluir_ids.
4) O segundo parâmetro seriam quais id´s seriam incluidas ou excluídas.

De cara pensei no padrão factory para as ações de incluir e excluir.

Mas ai entra também uma dúvida sobre a implementação desse padrão: A classe AcaoFactory seria a responsável por decompor e validar os parâmetros da string, e após isso atribuir para a classe correta ?

O que acham ?
Opinem por favor.[google]

Obs.: Vou tentar depois colar as classes aqui para vocês opinarem.

Obrigado.

public class AcaoRun {

    /**
     * @param args
     */
    public static void main(String[] args) {
        //Esse seria o parâmetro obtido da servlet
        String parametroDaSerlvet = "incluir_id={0001,0002,0003,0004}";
        
        Acao acao = AcaoFactory.getAcao( parametroDaSerlvet );
        if ( acao == null ){
            System.out.println("Acao nula");
            return;
        }
        
        acao.processarID();
        

    }
}




public class AcaoFactory {
    final static String ACAO_INCLUIR = "incluir_id";
    final static String ACAO_EXCLUIR = "excluir_id";
    private static String[] listaDeID;

    public static Acao getAcao(String param){
        // Caso fosse java 7 poderia utilizar Switch !!!
        if ( param.contains( ACAO_INCLUIR ) && validarIDs(param) ){
            return new Inclusao(listaDeID);

        }else if ( param.contains( ACAO_EXCLUIR ) && validarIDs(param) ){
            return new Exclusao(listaDeID);
        }

        return null;
    }

    public static boolean validarIDs( String parametro ){
        if ( parametro.contains("={") && parametro.contains("}") ){
            try {
                // Removendo caraceteres não utilizados
                parametro = parametro.replace(ACAO_INCLUIR, "");
                parametro = parametro.replace(ACAO_EXCLUIR, "");
                parametro = parametro.replace("={", "");
                parametro = parametro.replace("}", "");
                listaDeID = parametro.split(",");
                return true;
            } catch (Exception e) {
                // TODO: handle exception
                return false;
            }
        }
        return false;
    } 
}




public class Exclusao extends Acao {
    
    public Exclusao(String[] listaDeID) {
        this.setListaDeid(listaDeID);
    }

    @Override
    public void processarID() {
        // Realiza as eclusões dos ids ...... Exemplifico com esse for alguma coisa
        for (int i = 0; i < this.getListaDeid().length; i++) {
            System.out.println("Lista Exclusao " + getID(i) );
        }
    }
}



public class Inclusao extends Acao{

    public Inclusao(String[] listaDeID) {
        this.setListaDeid(listaDeID);
    }

    @Override
    public void processarID() {
                // Realiza as inclusões dos ids ...... Exemplifico com esse for alguma coisa
        for (int i = 0; i < this.getListaDeid().length; i++) {
            System.out.println("Lista Inclusao " + getID(i) );
        }
    }
}



public abstract class Acao {

/** Array onde os IDS que serão incluídos ou excluídos ficarão armazenados */
private String[] listaDeid;

    
    public void processarID(){}
    
    public void setListaDeid(String[] listaDeID2) {
        this.listaDeid = listaDeID2;
    }
    
    public String[] getListaDeid() {
        return listaDeid;
    }

        /*
         * Obtém um id da lista
         */
    public String getID( int id ){
        return this.listaDeid[id];
    }
}

Fernando Figueiredo

Fernando Figueiredo

Responder

Posts

22/02/2011

Davi Costa

O padrão Factory fornece uma interface para a criação de famílias de objetos correlatos ou dependentes sem a necessidade de especificar a classe concreta destes objetos. Por exemplo , quando estamos trabalhando com uma interface e temos mais de uma implementação para esta interface, podemos utilizar uma fábrica para criar um objeto que implementa a interface; a fábrica pode selecionar a implementação que ela retorna.Uma definição para o Factory seria, definir uma interface única para criação de objetos, deixando a cargo da classe Factory decidir qual instância de subclasse deve ser feita. Trocando em miudos, é como uma central telefonica, você liga para apenas 1 número que você conhece, pergunta para a telefonista o que deseja, e ele te retorna o número correspondido ao seu pedido.O que eu sugiro é, transforme sua classe AcaoFactory em um Singleton, para mantermos somente uma fábrica (por exemplo podemos citar a classe SessionFactory do Hibernate) na aplicação.Para a classe Acao deixe todos os métodos que serão sobrescritos como abstract. No seu caso vc já deu implementação para eles, mas em todos as classes que herdam de Acao sobrescreveram seus métodos o ideal então é deixá-los abstract e força a todos que o herdem que implementem seus métodos, obviamente algum método de Acao pode ter alguma implementação caso seja genérico para todas suas classes. você deixou métodos com implementação vazia, isso não é uma boa prática:public void processarID(){}Pois você pode esquecer de implementar esse método algum dia em alguma classe, vocês deixando esse método abstract força a classe filha a implementar este método.Dá uma olhada também na boa prática de implementar para interfaces e caso seus String forem restritos a poucas opções que tal utilizar Enum.
Espero ter ajudado.
Att Davi
Responder

22/02/2011

Fernando Figueiredo

Davi, muito obrigado por seus comentários e sus dicas.

Fora essas observações (muito importantes por sinal), teria mais alguma dica ?

Tipo, se existiria um padrão mais conveniente para realizar essa mesma tarefa ?

Qualquer dica para mim é valiosa, desde nome de atributos  até outra abordagem mais funcional e elegante.

Abçs.


Responder

22/02/2011

Davi Costa

Fernando,
realmente não é simples avaliar qual o melhor padrão de projeto, vai depender muito da necessidade e o que realmente é esperado da aplicação.

Um exemplo bem prático, se sua aplicação só tiver essa funcionalidade eu não usaria um Factory e atravessaria várias camadas para isso, mas se sua aplicação tiver outros propositos onde vc possa utilizar sua Factory ai sim valeria a pena. Mas fique tranquilo que o Factory casado com o Singleton como falei cabem bem na sua proposta.

Tem que saber a fundo os propósitos da aplicação, as regras de negócio, apesar desses propósitos e regras de negócio variarem bastante na construção de um software(desde mudança de requisitos, alteração na legislaçao.. e por aí vai) é muito importante termos uma idéia parcial do que a aplicação como um todo faz.

Acredito que é muito interessante, vc ver implementação para interfaces, vai facilitar bastante suas futuras manutenções, buscar também sempre o baixo acoplamento(diminuir a dependência de classes) e a alta coesão(classes bem específicas fazendo somente determinada função).

A respeito dos nomes das variáveis sugiro que siga a especificação do Java, segue inclusive uns links de artigos que falam um pouco do assunto:

https://www.devmedia.com.br/post-19153-Desmistificando-a-Certificacao-SCJP6-Parte-IV-Parte-2.html

https://www.devmedia.com.br/post-19152-Desmistificando-a-Certificacao-SCJP6-Parte-IV-Parte-1.html

Espero ter ajudado

Att Davi
Responder

24/02/2011

Dyego Carmo

Uma coisa que eu sempre digo... cuidado com padroes de projeto...

Não são balas de prata...

Use com parcimonia... caso contrario voce acaba criando uma torre de babel...

Responder

Assista grátis a nossa aula inaugural

Assitir aula

Saiba por que programar é uma questão de
sobrevivência e como aprender sem riscos

Assistir agora

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar