Não estou abandonando este blog (eu espero) mas agora também estou postando em um outro blog o Leandro Moreira lá pretendo escrever e abordar assuntos de desenvolvimento de sistemas do mesmo modo que aqui só que em inglês. :)
A arte de desenvolver, entender e manter sistemas
Software, distribuindo informação.
Pesquisar
quarta-feira, 20 de abril de 2011
quinta-feira, 7 de abril de 2011
A experiência do TDD na vida de um desenvolvedor
Pré-TDD
Ferramentas que conhece: JUnit :(
Prefere criar um public static void main(String[] args) e usar Alt+Shift+X + J ao criar uma ClasseTest com um método anotado com @Test.
Pós-TDD
Materiais para ajudá-lo na busca pelo TDD
Link: http://improveit.com.br/xp/praticas/tdd/
Livro: TDD by example (traduzido para pt_BR)
só pra lembrar: test fails, test passes, refactor
Um pouco cético quanto ao processo mas estudando e lendo opiniões que fazem sentido, logo você "compra" a ideia. No inicio escreve-se os testes depois que (quase) tudo foi feito e o pior é o vício de escreve-los para que os mesmos funcionem. Nessa fase não se vê nem o beneficio real que os testes unitários trazem (nem mesmo a "metodologia" TDD traz). As perguntas mais freqüentes nessa era são:
Devo testar os CRUD's? Devo testar Getters and Setters simples?
Sintomas: perdendo tempo escrevendo testes (pós-testes)Ferramentas que conhece: JUnit :(
Prefere criar um public static void main(String[] args) e usar Alt+Shift+X + J ao criar uma ClasseTest com um método anotado com @Test.
Pós-TDD
Você (realmente) sente inseguro quanto olha pra massa de testes e vê que novas (ou antigas) funcionalidades não estão sendo testadas, de alguma forma não ter os testes te causa uma sensação terrível de que está faltando algo. Suas idéias nascem pensando em testes (indo para BDD) você muda mesmo a forma de pensar. Você (realmente) sabe do valor inestimável de se ter testes para rodar antes de um build. Começa a achar estranho o desaparecimento de bugs esporádicos. Tem toda certeza que quase todo pedaço de código pode gerar bug inesperado. Ferramentas que já conhece e não vive sem : Mockito, Maven, Hudson... Ferramentas que começam a despertar seu interesse: JBehave, Selenium. Claro que algumas dessas ferramentas não estão ligadas diretamente ao TDD mas sim ao modo de pensar em testes e automação dos mesmos. Testes de software é algo complexo, extenso e sempre em evolução mas é uma maneira eficiente de diminuir os erros na criação ou manutenção de software.
Link: http://improveit.com.br/xp/praticas/tdd/
Livro: TDD by example (traduzido para pt_BR)
só pra lembrar: test fails, test passes, refactor
Marcadores:
java,
tdd,
test-driven development,
testes,
testes unitarios
quarta-feira, 16 de março de 2011
Novo projeto WetSand
O que estive fazendo...
Estou tentando reduzir meus (re)trabalhos para criação de CRUD's. O resultado desse esforço é a ideia de criar um framework pra aumentar a produtividade na criação de CRUDS. O conceito principal é que você tem uma API e pode provê várias implementações para essa API (W0). Isso tudo não é nenhuma novidade, apenas minha tentativa de padronizar a criação de CRUDS.
WetSand
É o conjunto de projetos para criação de aplicações que vão inevitavelmente ter CRUDs.
W0 - A API base
A arquitetura básica está toda nesse projeto, que é fortemente baseado nos conceitos de Domain-Driven Design (DDD). Infelizmente o conceito de arquitetura de referência é empregado aqui, engessar sua aplicação tem vários efeitos colaterais e más implicações mas foi o jeito que encontrei de "criar" uma estrutura, até certo ponto flexível, para servir genericamente para isso. Resumidamente um arquitetura de referência te força a usar a mesma estrutura para matar uma "barrata" e matar uma "baleia" por outro lado há uma padronização de interfaces e mensagens entre os componentes, o que para a criação de CRUD's pode ajudar muito.
W1 - Primeira implementação JPA 2.0, Spring 3.x.x, JSF 2.0
Para ter mesmo certeza que tal API poderá ser útil, trabalho na primeira implementação dessa API. Essa implementação utiliza JPA 2.0, Spring 3.x.x, JSF 2.0 e Primefaces 2.2.1 dentre suas dependências. Foram criados os subprojetos:
O projeto exemplo já está rodando mas ainda considero longe de uso em produção ou algo assim, está na fase de evolução. Logo, toda e qualquer sugestão ou crítica será bem vinda. Penso em criar implementações compatíveis para Richfaces 4.0, VRaptor 3, GAE e GWT para realmente testar se é possível que essa API e suas implementações possam diminuir o retrabalho de CRUDS. Também há um gerador de CRUD mas esse é bem específico e a única implementação que tem é para o W1X.
Enfim
Se o projeto não servir de nada talvez ele sirva de exemplo de como construir telas usando JSF 2.0, components do facelets, usar o primefaces, utilizar o Spring 3.x.x juntamente com JPA 2.0, bem como Maven e outras boas práticas de "novas" tecnologias. Logo terá uma documentação básica com um Quick Start e demonstração de exemplos.
WetSand
É o conjunto de projetos para criação de aplicações que vão inevitavelmente ter CRUDs.
W0 - A API base
A arquitetura básica está toda nesse projeto, que é fortemente baseado nos conceitos de Domain-Driven Design (DDD). Infelizmente o conceito de arquitetura de referência é empregado aqui, engessar sua aplicação tem vários efeitos colaterais e más implicações mas foi o jeito que encontrei de "criar" uma estrutura, até certo ponto flexível, para servir genericamente para isso. Resumidamente um arquitetura de referência te força a usar a mesma estrutura para matar uma "barrata" e matar uma "baleia" por outro lado há uma padronização de interfaces e mensagens entre os componentes, o que para a criação de CRUD's pode ajudar muito.
W1 - Primeira implementação JPA 2.0, Spring 3.x.x, JSF 2.0
Para ter mesmo certeza que tal API poderá ser útil, trabalho na primeira implementação dessa API. Essa implementação utiliza JPA 2.0, Spring 3.x.x, JSF 2.0 e Primefaces 2.2.1 dentre suas dependências. Foram criados os subprojetos:
- W10 - A implementação para os Dao's (CrudDao) baseada no JPA 2.0 bem como a implementação da API Query.
- W11 - A implementação base para o CrudRepository.
- W12 - A implementação base para o CrudService.
- W13 - A implementação base para o ManagedBeanCrudController que é uma especificação do controlador mais genérico CrudController.
O projeto exemplo já está rodando mas ainda considero longe de uso em produção ou algo assim, está na fase de evolução. Logo, toda e qualquer sugestão ou crítica será bem vinda. Penso em criar implementações compatíveis para Richfaces 4.0, VRaptor 3, GAE e GWT para realmente testar se é possível que essa API e suas implementações possam diminuir o retrabalho de CRUDS. Também há um gerador de CRUD mas esse é bem específico e a única implementação que tem é para o W1X.
Enfim
Se o projeto não servir de nada talvez ele sirva de exemplo de como construir telas usando JSF 2.0, components do facelets, usar o primefaces, utilizar o Spring 3.x.x juntamente com JPA 2.0, bem como Maven e outras boas práticas de "novas" tecnologias. Logo terá uma documentação básica com um Quick Start e demonstração de exemplos.
Marcadores:
crud,
ddd,
domain-driven design,
framework,
gerador código,
java,
jpa 2,
jsf 2,
maven,
open source,
richfaces 4.0,
spring 3,
wetsand
terça-feira, 4 de janeiro de 2011
Segurança, CCC, Assinatura digital, Consoles...
O CCC - Chaos Computer Club promoveu, esse ano, um evento que mostrou muitos fatos interessantes. Em uma das apresentações o grupo fail0verflow demonstrou um pouco da história das falhas de segurança nos consoles da nova geração (Wii, Xbox 360, PS3). E foi interessante ver o modelo de segurança do PS3 e como eles desvendaram as chaves privadas do mesmo, eu só conhecia bem superficialmente o modelo de segurança do Wii. Se você interessa por segurança, consoles e hacking é uma ótima apresentação.
http://www.youtube.com/watch?v=hcbaeKA2moE
[update] - Parece que a chave do PSP estava "dentro" do PS3 agora tanto a cena do PSP e PS3 podem, teoricamente, escrever e rodar código dentro das plataformas da sony.
http://www.youtube.com/watch?v=hcbaeKA2moE
[update] - Parece que a chave do PSP estava "dentro" do PS3 agora tanto a cena do PSP e PS3 podem, teoricamente, escrever e rodar código dentro das plataformas da sony.
[update] - Baixe a apresentação do evento. A BBC também noticiou o fato da descoberta do conjunto de chaves que a Sony usa para o PS3 e PSP.
Marcadores:
algoritmo,
assinatura digital,
chaos computer club,
chave privada,
consoles,
falha,
firmware,
hacking,
ps3,
seguranca,
wii
quinta-feira, 4 de novembro de 2010
A prática do SEO e os resultados
Apesar de ter um trabalho fixo; hora ou outra também executo trabalhos freelancer java. E ultimamente as propostas de trabalho tem aumentado consideravelmente. E esse aumento se deve (na maioria absoluta) ao uso de um conjunto de técnicas (e ou estratégias) SEO.
É impressionante o quanto o google pode lhe dar retorno com um bom posicionamento, e digo isso baseado apenas no lucro que obtive em pequenos trabalhos ou ajuda (consultória) em Java, Richfaces, JSF, JPA enfim...
Por isso e outros fatores noto que a propaganda paga ao google é um investimento que tem retorno garantido. Só pra esclarecer não tenho nenhum vinculo com google (empregatício porque de uso muito de seus serviços).
Para se ter uma ideia, se você procurar por freelancer java no google, o blog vem em 5º lugar (claro esse posicionamento vai se atualizar) e com esse "5º lugar" noto que a diferença de divulgação por email, forum e etc é extremamente irrisória se comparada ao jeito google de ser.
Portanto fica aqui a dica se não conhece vale a pena dar uma estudadinha em SEO e suas consequências.
É impressionante o quanto o google pode lhe dar retorno com um bom posicionamento, e digo isso baseado apenas no lucro que obtive em pequenos trabalhos ou ajuda (consultória) em Java, Richfaces, JSF, JPA enfim...
Por isso e outros fatores noto que a propaganda paga ao google é um investimento que tem retorno garantido. Só pra esclarecer não tenho nenhum vinculo com google (empregatício porque de uso muito de seus serviços).
Para se ter uma ideia, se você procurar por freelancer java no google, o blog vem em 5º lugar (claro esse posicionamento vai se atualizar) e com esse "5º lugar" noto que a diferença de divulgação por email, forum e etc é extremamente irrisória se comparada ao jeito google de ser.
Portanto fica aqui a dica se não conhece vale a pena dar uma estudadinha em SEO e suas consequências.
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 . 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.
E apartir desse MB crio os meus outros CRUDS simples, exemplo telefone:
Ó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:
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 :
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.
Invejando descaradamente o conto de cada dia do Phillip . 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{Mas será que não pode ser melhorado?!
private ManagedBeanCRUD[Telefone, Integer] delegate;
public String salvar(){
return delegate.salvar();
}
// + do mesmo
}
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{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.
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;
}
}
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.
Marcadores:
arquitetura,
boas praticas,
caelum,
design,
domain-driven design,
fragmental,
java,
jsf,
modelagem,
oo,
padrões,
programacao,
projeto de software,
projeto oo,
refatoração
Assinar:
Postagens (Atom)