Pesquisar

Mostrando postagens com marcador boas praticas. Mostrar todas as postagens
Mostrando postagens com marcador boas praticas. Mostrar todas as postagens

terça-feira, 10 de agosto de 2010

Decisões de design - Herança X Composição

Mesmo que esse assunto pareça já explorado de todas as formas ainda há certas situações que relutamos (pelos menos eu) em usar a herança ao invés da composição.
Invejando descaradamente o conto de cada dia do Phillip http://images.americanas.com.br/produtos/item/2508/8/2508843gg.jpg. Vou contar de uma experiência que tive. O exemplo clássico é o controlador CRUD (seja seu servelet, managed bean, action form... ) que contém os métodos para uso geral e genérico e alguns ganchos. Vou dar um exemplo bem simples de um Managed Bean CRUD.

public class ManagedBeanCRUD [E,ID]{
private E instancia;
public E getInstancia(){return instancia;}
public Void setInstancia(E entidade){this.instancia = entidade;}

public String salvar(){
preSalvar();
servicoCrud.salvar(getInstancia);
return "navegacaoListar";
}
public void preSalvar(){}
}

E apartir desse MB crio os meus outros CRUDS simples, exemplo telefone:

public class TelefoneMB extends ManagedBeanCRUD [Telefone, Integer] {
@Override
public void preSalvar(){
System.out.println("Oi esse é gancho ...");
}
}

Ótimo, houve reuso por meio da herança mas logo veio as seguintes perguntas: porque não transformou os métodos preXXX em métodos abstratos? Porque daí eu teria que obrigar o usuário a implementar sempre mesmo quando não fosse necessário. porque não usou composição ao invés da herança? Porque minha visão (xhtml) já está toda padronizada.

[c:campoentrada binding="#{mb.instancia.numero}"/]
[c:botao binding="#{mb.salvar}"/]

Note que o método salvar não existe (ao menos no fonte) na classe TelefoneMB ele é acessado por herança. A primeira tentativa foi substituir a herança por composição por meio de delegação, minha classe TelefoneMB ficaria mais ou menos assim:

public class TelefoneMB{
private ManagedBeanCRUD[Telefone, Integer] delegate;
public String salvar(){
return delegate.salvar();
}
// + do mesmo
}
Mas será que não pode ser melhorado?!

Claro que sim até agora consegui chegar num patamar assim: os métodos ganchos se transformam no padrão decorator e a herança se torna composição por delegação mas de um modo diferente, fiz o MangedBeanCRUD ser um atributo de leitura :

public class TelefoneMB{
private ManagedBeanCRUD[Telefone, Integer] crud;

public TelefoneMB(){
crud.addEventoPreSalvar(new Evento(){
public void executar(){
System.out.println("antes de salvar...");
}
});
}

public ManagedBeanCRUD getCrud(){
return crud;
}
}
E na view (jsf, xhtml ...) não terei muita mudança será uma navegação a mais na #EL #{telefonemb.crud.salvar} terei que adicionar o crud antes do padrão CRUD de ser.

Com isso tenho um managed bean livre de más práticas, melhorei o sistema de eventos e mais um plus não terei problemas futuros com proxies do JDK ou GLIB2! Mais camadas e indireções sempre foi o caminho conforme post sobre abstrações pra todo lado.

Todo comentário sempre é e será bem-vindo!

ps: só pra deixar claro não sou contra o uso da herança, há casos que você pode usar herança para compor suas entidades e outros n usos. O único cuidado que deve ter é pensar, pensar, pensar e pensar para decidir se é herança ou não.

terça-feira, 9 de março de 2010

boasPraticas.add deploy, tdd, ddd

Recebi a visita de um super amigo das antigas (leia-se VB.NET), eu tinha que entegrar um simples gerenciador de conteúdo e meu amigo me acompanhou e ficou questionando sobre por que eu fazia assim, usava aquilo, não fazia isso... no fim ele disse que precisava de desenvolver com mais qualidade, controle e facilidade. Ele ainda me pediu uma lista de livros pra ler e quais praticas eu usava, naquele momento começei a falar tanta coisa, ferramenta, framework, metodo... que ele mesmo disse "escreva uma lista dessas boas práticas"! E aqui estou eu, vou tentar apenas listar os tópicos e os links que acho interessante.

Não reivente a roda - quase sempre há uma common pronta, então quando surgir uma necessidade pesquise antes sobre o assunto. Tive uma péssima experiência com um agendador de tarefas (que eu criei) em Java, tudo isso porque não conhecia o Quartz.
Melhore seu design OO - por mais que pareça esgotado esse assunto, ainda há pessoas que não compreendaram assuntos básicos, esse tópico (sobre OO) não dá pra ser resolvido com uns poucos links mas se eu pudesse indicar um site seria o do Philip Calçado. PS: outras boas práticas abaixo listadas podem lhe ajudar também num design mais charmoso.
TDD - uma ótima prática que pode lhe livrar de dores de cabeças infernais. No inicio pode parecer perda de tempo mas com tempo você vai ver o valor de usar Test Driven Development.
Logging - não há nada mais chato do que ler grandes arquivos de logging não é mesmo?! Há sim, debugar! :P então: prefira Logar do que Degubar! Pode começar lendo um tutorial de log4j.
Deploy - Automatizar suas construções e criar um processo de deploy continuo :)
Boas práticas com JPA - às vezes passamos raiva só por desconhecimento (profundo) de um certo recurso do framework. Logo digo leia esse ótimo post sobre os bons habitos de usar JPA.
Integração continua - Leia o post de Integração continua ahhh outra dica automatize tudo o possível.
Aprenda outra linguagem - Sua cabeça pode se tornar viciada numa linguagem só e isso pode lhe privar de conhecer ou melhor entender como outros organismos funcionam. Além do mais é divertido aprender Ruby e ver como as pessoas resolvem problemas de maneiras tão distintas.
Comunidade - Nem só de código fonte a comunidade open-source se alimenta, usar forums para aprender e ensinar é algo muito valioso.
Outros bons livros :)

Tudo isso pode parecer plágio de um grande blog de ótimo desenvolvedores, mas não é :) Juro!