sexta-feira, 29 de maio de 2009

[Noticia] Como o TDD e a programação em par aumentam a produtividade

Bem, acredito que vai ser difícil achar uma notícia que esteja mais no contexto desse blog que essa. O conteúdo dessa matéria da InfoQ diz tudo que eu sempre debati com as pessoas que questionam a necessidade de um software de qualidade.

Como diz o grande Shoes, Programadores Profissionais Escrevem Testes, Ponto Final.

Isso deveria ser óbvio, mas infelizmente, não é. Nas grandes empresas, onde existe divisão de papéis, quase sempre bem definida, conhecemos desenvolvedores dizendo que não tem a responsabilidade de testar.

O fato da empresa possuir uma equipe de testes, não exime o programador de testar o que fez. Verificar se o que foi implementado cumpre os requisitos é obrigação de todo desenvolvedor. Leia o texto do Philipp e tente não se convencer disso.

Uma suite de testes bem feita garante a qualidade do trabalho do profissional e, parodiando o Shoes, ponto final.

A questão do pair-programming já é um pouco mais complicada, já que envolve a alocação de dois colaboradores da empresa para a mesma tarefa. Essa técnica pode gerar discussões como: É impossível escrever todo o código em pares. Será muito lento. E se duas pessoas não se entenderem? A não ser que:
  • Os padrões de codificação reduzam brigas mesquinhas;
  • todo mundo esteja descansado e tranquilo, reduzindo mais ainda a chance de discussões não proveitosas;
  • os pares escrevam testes juntos, o que dá a eles a chance de se sintonizarem antes de começarem a implementação;
  • os pares tenham a metáfora para apoiar suas decisões sobre nomeação e projeto básico;
  • os pares estejam trabalhando com um projeto simples, para que os dois entendam o que está acontecendo.
Trecho retirado do livro Programação Extrema Explicada - Kent Beck.

O próximo artigo da série princípios de projeto está quase pronto. Será abordada a questão da eficiência.

Sites Relacionados:
Fonte da Notícia: InfoQ

quarta-feira, 27 de maio de 2009

[Notícia] Java Persistence 2.0 Proposed Final Draft

Saiu o final draft da especificação da JPA 2.0.

A criteria API permitirá a criação de queries a partir de chamadas de métodos, em vez de JPA-QL em Strings que são parseadas pela JPA. Acredito que API ficará mais Java Friendly. Ouvi muito essa expressão durante a apresentação do VRaptor 3, no último Falando em Java.

King recentemente sugeriu um refactoring para extender o typesafety para o resultado das queries, adicionando parametrização em Query e CriteriaQuery. Isso pode gerar warnings nos projetos baseados na JPA 1.0, já que a classe javax.persistence.Query, atualmente, não permite parametrização.

Sites Relacionados:
InfoQ
Gavin King
DZone
Linda DeMichiel

[Notícia] O Poder do Infoblogs

Desde que meu blog entrou no InfoBlogs, houve um estouro de visitas e page views.

Visitas:
Média diária: Aumento de 220%
Record: Aumento de 300%

Fiquei impressionado com o poder do site.

Hoje, com a moderação de conteúdo, o InfoBlogs está caminhando para um futuro onde a excelência de conteúdo será a sua principal preocupação.

Assim, tenho o orgulho de informar que faço parte desse time, e vou me esforçar para, junto com a equipe de moderadores, garantir conteúdo de qualidade a todos os usuários.

E vamos que vamos!

terça-feira, 26 de maio de 2009

Falando em Java 2009 - Minhas impressões



A organização está de parabéns. O único problema que notei foi a dificuldade para acessar as mesas durante o coffee break. Acho que mais mesas resolveriam este problema. Como meu coffee break normalmente se resume a apenas coffee, não tive muito do que reclamar. O coquetel de encerramento foi ótimo, pois a cerveja não estava difícil de acessar.

De resto, espaço, iluminação, som, conforto, atendimento, limpeza, acesso ao local, nota 10.

Agora vamos ver o que achei das palestras. Passarei apenas as minhas impressões, sem entrar muito nos detalhes técnicos, já que o André Pantalião e o Rodrigo Ribeiro já fizeram isso de forma magistral.

Acesse, também, as fotos do evento.


Keynote: Guerrilha SOA
Jim Webber

O Jim cumpriu muito bem o seu papel de estrela do espetáculo e sua palestra foi impecável. Para mim, os pontos altos do dia foram as suas palestras de abertura e de encerramento.

Webber falou de assuntos sobre os quais eu havia visto muito pouco. Mesmo assim, não deixou de me surpreender. Jim se mostrou contra o ESB mostrando que a WEB é um grande middleware. É a "ponte de ligação entre os silos". Uma das motivações para essa abordagem, segundo Webber, é a escalabilidade. Uma grande preocupação que me ocorreu, foi a questão da segurança.

Sites relacionados:
http://jim.webber.name/downloads/presentations/2009-05-Falando-em-Java-Keynote.pdf


O Profissional Java Efetivo
Paulo Silveira e Rafael Consentino

Não achei que o título representou o conteúdo da palestra, o que não diminui a qualidade do conteúdo. Na minha opinião, um título mais adequado seria: O Profissional de Integração Efetivo, já que algumas técnicas de integração foram apresentadas e, com uma simulação do mundo real, mostraram as decisões mais acertadas, pontos fortes e pontos fracos de cada decisão e, finalmente, onde foram buscar embasamento para cada tomada de decisão.

Os palestrantes demonstraram muita sincronia e tranquilidade quanto ao assunto abordado.


JBoss Sean e WebBeans

Alessandro Lazarotti e Ricardo Nakamura

Os palestrantes, também muito fluentes no assunto, usaram um processo bem simples e palpável, pois dizia respeito a um processo do mundo real (a rotina do Nakamura para ir trabalhar) para explicar um assunto não tão simples: A Injeção de Dependência.

Demonstraram bem como o WebBeans é a implementação da JSR 299, deixando claro a diferença entre especificação e implementação. Mostraram que o Sean é um "superset" dos WebBeans, sendo o segundo um "core programming model" do primeiro.

Sites relacionados:
http://jcp.org/en/jsr/detail?id=299
http://seamframework.org/
http://seamframework.org/WebBeans


VRaptor 3: Gurrilha WEB
Felipe Sabella e Guilherme Silveira

Foi uma palestra bastante prática, demonstrando como o VRaptor pode facilitar a vida do desenvolvedor WEB. Explicaram que esse framework nasceu de algumas necessidades não cobertas pelo WebWork 2.0, que na época do surgimento do VRaptor, ainda se encontrava na versão beta. Ficou claro como o framework contém o que eles consideram de melhor nos frameworks já existentes no mercado.

Também gostei muito da fluência dos palestrantes e dou um destaque para a didática do Guilherme.

Até então, só tinha ouvido falar do VRaptor. A palestra me convenceu que ele pode ser útil para o meu dia a dia.

Sites Relacionados:
http://www.vraptor.com.br/
http://github.com/caelum/vraptor/tree/master


Arquitetura para aplicações Java de médio porte

Guilerme Moreira e Sérgio Lopes

Também foi uma palestra bem prática. Demonstraram algumas técnicas para tornar o Hibernate mais eficiente, como por exemplo o uso de StatelessSession.

Houve um problema durante a demonstração da
clusterização, pois a queda de uma máquina não estava sendo detectada. Os palestrantes mostraram habilidade para lidar com situações adversas. Ainda acredito que a não detecção da queda da máquina foi culpa da rede wireless. O Sérgio Lopes, já sabendo que algo ruim poderia acontecer, devido a complexidade do que eles pretendiam fazer, no início da demonstração sentenciou: "Macho que é macho demonstra Load Balacing ao vivo."

A fluência dos palestrantes também me agradou bastante.


Para onde vai a Plataforma Java? Linguagens dinâmicas, JavaTV, JavaFX e além.
Anderson Leite e Fábio Kung

Foi a que mais decepcionou. Não me agradaram algumas novidades, como a proposta de uso de propriedades. Também achei os blocos de código algo confuso. Essa última questão, como o Fábio mencionou durante a apresentação, pode ser uma questão de costume. A novidade positiva, sob meu ponto de vista, é o Da Vinci Machine Project.

O Anderson Leite me pareceu nervoso. Seu timing não estava bom, na minha opinião. Entretanto, ele demonstrou conhecimento sobre o que falava e, falta de timing, é algo que pode ser melhorado com a prática. No GUJ ele informou que estava tentando um novo estilo de palestrar, o que também é louvável, pois mostra uma preocupação com a excelência.


Web Services Restful: Putting Java to REST
Jim Webber

Mais uma vez Jim nos brindou com sua fluência. Falou de RESTFul Web Services, assunto que estava destinado a Bill Burke, que teve problemas com seu visto para o Brasil. Mostrou um estudo de caso, um Coffee Shop. Este artigo na InfoQ, possui 90% da palestra de encerramento do Jim.

Encerrou, com seu bom humor, dizendo que se tivéssemos gostado da palestra ele era Jim Webber, caso contrário era Bill Burke.

Foi sempre atencioso nos corredores, conversando com as pessoas que se aproximavam. Palestrou como legítimo Rock Star Programmer, e se portou como simples mortal. Agiu de forma impecável.

Sites relacionados:
http://jim.webber.name/presentations.html

sexta-feira, 22 de maio de 2009

[Notícia] Dependency Injection for Java

A JSR 330 foi submetida ao JCP e a proposta oficial é maximizar a reusabilidade e facilitar a execução de testes e a manutenção, padronizando a API de injeção de dependência do Java.

Esta JSR foi um esforço conjunto do Goggle e do SpringSource.

Bem, acho que a importância dessa notícia resida na recente compra da Sun pela Oracle. Muitas pessoas entraram em desespero, desconfiando da força da comunidade. Mas este recente apoio do Google demonstra como as grandes empresas continuam acreditando.

É verdade, é bem provável que essa JSR já tenha sido planejada há tempos, mas é bem provável, também, que uma empresa do tamanho do Google tenha antevisto a compra da Sun. Dessa forma, considero uma prova de confiança na manutenção da comunidade controlando o Java.

No site da InfoQ tem uma enquete que visa saber a utilidade dessa JSR.

Fonte: InfoQ
Notícia: Noticia Oficial
JSR: http://docs.google.com/Doc?id=dd2fhx4z_22g7x8zdfn

Identificação da JSR 330:
JCP members submitting this proposal: Google and SpringSource
Name of Contact Person: Bob Lee and Rod Johnson
Name of Specification Lead: Bob Lee and Rod Johnson
Initial Group Membership: Google, SpringSource
Supporting this JSR: Joshua Bloch, Paul Hammant (ThoughtWorks, PicoContainer founder), Doug Lea, Tim Peierls, James Strachan, Hani Suleiman, Jason van Zyl (Maven, Plexus), Thiago H de Paula Figueiredo (Tapestry IoC)

quarta-feira, 20 de maio de 2009

Princípios de projeto - Parte V - A Lei de Demeter

A Lei de Demeter foi concebida por volta de 1987, definindo uma forma de desenvolver, também conhecida por Princípio do Mínimo Conhecimento (Principle of Least Knowledge). A lei tem origem em bla bla bla, e seu nome deriva de bla bla bla

Formalmente falando, um método M de um objeto O só pode consumir serviços dos seguintes tipos de objetos:

  1. Do próprio objeto O;
  2. Parâmetros de M;
  3. Qualquer objeto criado/instanciado por M;
  4. Componentes diretos de O.
Existe teoria abundante na Internet sobre a Lei. Os objetivos desse post são: mostrar/lembrar aos leitores desse blog que a Lei existe; criar uma referência centralizada para posts futuros e..... mostrar o exemplo do cachorro na prática. Exemplo do cachorro?!?!!

A grande maioria do material sobre a lei na Internet, usa o exemplo do cachorro:

Quando você precisa que um cachorro ande, você dá a ordem para as pernas diretamente, ou para o cachorro? Obviamente que para o cachorro e este sabe o que precisa ser acionado para andar.

Vamos demonstrar essa teoria:

package br.com.celsomartins.cachorro;
import java.util.ArrayList;
import java.util.List;

public class Cachorro {

private List <Pata> patas = new ArrayList <Pata>();

  public boolean andar() {
      for (Pata pata: patas) {
           if (!pata.andar()) {
               return false;
           }
       }
       return true;
  }
}


package br.com.celsomartins.cachorro;

public class Pata {
 
  public boolean andar() {
    return true;
  }
}

O que a Lei de Deméter diz é para não enviarmos mensagens para Pata e sim para Cachorro, que fará a delegação para as patas e estas para as classes que forem necessárias para fazer o cachorro andar.

A diferença é clara:

disso:

...
for (Pata pata: cachorro.getPatas()){
 pata.andar();
}

para isso:

cachorro.andar();

Dá para notar a facilidade de manutenção nesse exemplo? Posso alterar o comportamento das patas e o cão continua andando, sem afetar o cliente da classe Cachorro. O cachorro pode ter perdido uma das patas e andar com apenas três, isso não é importante para o cliente da classe.

A complexidade da ação está encapsulada. Não é preciso ninguém saber quais músculos, ossos, tendões, etc estão envolvidos na ação. Isso não é problema de quem está dando a ordem para o cão. Com a complexidade encapsulada, reduzimos dependências desnecessárias, facilitando a manutenção, aumentando a flexibilidade do nosso sistema.

Outro exemplo prático podemos encontrar nesse artigo.

Até a próxima.


Parte I - Introdução
Parte II - Correção
Parte III - Design por contrato
Parte IV - Flexibilidade
Parte VI - Eficiência
Parte VII - Coesão
Parte VIII - Usabilidade
Parte IX - Relacionamento entre classes

terça-feira, 19 de maio de 2009

Tutoriais TDD

Acabei de pescar um post da InfoQ, com vários links para tutoriais de TDD. Já dei uma olhada em alguns e acredito que possa ajudar bastante as pessoas que estão querendo aprender esta técnica.

Segue o link: http://www.infoq.com/news/2009/05/recommended-tdd-tutorials

Enjoy

segunda-feira, 18 de maio de 2009

Site sobre qualidade

Descobri, no InfoBlogs, este site na semana passada.

O conteúdo me impressionou e a variedade de formas de informar: blogs, fóruns, notícias, etc.

O Fábio é focado em qualidade e fala muito em testes.

Ainda não li tudo, mas os artigos que li pareceram muito sensatos.

O enfoque é diferente do foco dado nesse blog, mas o objetivo é o mesmo: produzir softwares de qualidade. Foi o que pude perceber até agora.

Vale a pena conferir.

Reforçando, segue o link para o site: http://www.testexpert.com.br/

sexta-feira, 15 de maio de 2009

Princípios de projeto - Parte IV

Agora falaremos da flexibilidade. O princípio da flexibilidade diz respeito a como sua aplicação é capaz de se adequar às mudanças solicitadas na aplicação.

Mudanças acontecem a todo momento durante o processo de software. Sua aplicação deve estar preparada para isso. A ausência deste princípio gera, naturalmente, um receio por mudanças. É a ausência desse princípio que produz as tão famosas reclamações da equipe com relação ao cliente.

Basicamente, existem dois tipos de Change Requests: o que é ocasionado pela deficiência no levantamento de requistos e o que é ocasionado por mudanças no negócio do cliente.

Como fazer com que essas alterações não transformem nossas vidas em um inferno?

Um desenvolvedor preocupado com as boas práticas produzirá códigos mais flexíveis. Usaremos, para exemplificarmos, o primeiro exemplo de qualidade na prática.

Cenário: o cliente nos informa que, a partir de agora, para solicitação de compras de produto de um pedido, primeiramente, será preciso verificar se o mesmo está confirmado.

Solução com o código primitivo: Descobrir qual valor corresponde ao status confirmado. Verificar se o status do pedido é igual ao valor de confirmado.

Solução com o código refatorado: Perguntar se o status é confirmado, através do método estahConfirmado(short status).

É válido notar que, numa solução OO, o método estahConfirmado(), é uma operação (comportamento) de um objeto de uma classe, Pedido por exemplo. Dessa forma, sempre que precisássemos confirmar se o status de um pedido está em conformidade com a operação que desejamos realizar, pergutamos para quem sabe, isto é, para o objeto.

Onde a flexibilidade do código refatorado? Bem, logo de cara, percebemos que não precisamos duplicar código para verificar o status. Dessa forma, estaremos reusando um código que já foi testado diversas vezes. O analista de negócios solicitou uma alteração e a fizemos somente realizando mais uma chamada a um método já existente.

Outro exemplo interessante, surgiu nessa thread do GUJ:

Cenário: O desenvolvedor precisa de uma pilha limitada.

A primeira solução que forneci é, na verdade, uma gambiarra. Na segunda, aproveitei a flexibilidade do Java para fornecer uma solução mais elegante.

Outro exemplo clássico que prova a flexibilidade do código refatorado é a mudança da lógica de negócios para o status confirmado. Nenhum cliente do objeto da classe Pedido precisa saber que o chato do cliente mudou a lógica. Faremos a alteração na classe Pedido e nenhuma outra alteração será necessária. Essa flexibilidade é um dos motivos para o Shoes e Fowler serem contras a separação de dados e comportamento em VO e BO, produzindo um modelo anêmico.

Outras formas de conseguir flexibilidade é eliminando dependências desnecessárias e melhorando a legibilidade. Por consistirem em assuntos vastos, falaremos mais adiante.

A flexibilidade é subjetiva, difícil de perceber. Normalmente, só a percebemos quando precisamos. Portanto poderíamos escrever milhares de linhas e ainda não cobriríamos todo assunto. Espero que a idéia central tenha sido passada.

No próximo post, falarei da Lei de Deméter. Até lá.

Parte I - Introdução
Parte II - Correção
Parte III - Design por contrato
Parte V - A Lei de Demeter
Parte VI - Eficiência
Parte VII - Coesão
Parte VIII - Usabilidade
Parte IX - Relacionamento entre classes

terça-feira, 12 de maio de 2009

Princípios de Projeto III - Design por contrato

Bertrand Meyer descreve as pré e pós-condições de uma operação como design por contrato. Invariantes são condições que todo objeto de uma determinada classe deve satisfazer em todo ciclo de vida, enquanto estiver em equilíbrio, isto é, não estiver numa mudança de estado.

Um exemplo de invariante, dado por Page-Jones é sobre um objeto da classe Triangulo.
Sabendo que os lados de um triângulo são Triangulo.a, Triangulo.b, Triangulo.c, então uma parte da invariante de classe de Triangulo é: a + b > c and b + c > a and c + a > b.
A pré-condição é uma condição que deve ser verdadeira antes do início da execução da operação. Se não for, a operação pode recusar executar e lançar alguma excessão. Uma pós-condição é uma condição que deve ser verdadeira no fim da execução da operação.

Interfaces são outra forma de design por contrato. Quando uma determinada classe afirma que implementa uma interface, ela deve, obrigatoriamente, implementar todas as operações que estão definidas nesta interface. Existe um excelente artigo aqui sobre o assunto.

Enfim, invariantes, pré e pós-condições e interfaces formam uma abordagem de design conhecida como "Design por Contrato". Esta abordagem garante que uma operação de um dado objeto vai gerar a resposta correta, para o objeto cliente (objeto que está consumindo o serviço), ao mesmo tempo que obriga o objeto cliente a obedecer as pré-condições do serviço que está consumindo. Também obriga a implementação das operações que estão definidas na interface implemetada.

Referência: Fundamentals of Object-Oriented Design in UML by Meilir Page-Jones

Parte I - Introdução
Parte II - Correção
Parte IV - Flexibilidade
Parte V - A Lei de Demeter
Parte VI - Eficiência
Parte VII - Coesão
Parte VIII - Usabilidade
Parte IX - Relacionamento entre classes

segunda-feira, 11 de maio de 2009

Princípios de projeto - Parte II

Existem alguns motivos principais para um sistema não atender os requisitos para os quais foi contratado o projeto. Vamos analisa-los:
  • Muitas pessoas entre o cliente e a equipe de desenvolvimento: Os requisitos podem chegar deturpados até os desenvolvedores. Não é culpa da equipe, nem do cliente. Simplesmente, o telefone sem fio não funciona com precisão em área alguma, ainda mais em engenharia de software. Em algumas empresas, a equipe de desenvolvimento, não chega a participar das reuniões de levantamento de requisitos. Assim, os problemas são propagados pelas camadas da empresa, "cascateando" o mal entendido do cliente para o analista, deste para o líder e deste para a equipe. Ainda não tive experiência com esse tipo de divisão de papéis. Com as empresas que trabalhei até hoje, o papel do analista esteve sempre vinculado ao papel do programador. Nos locais onde atuei, a vontade do cliente chega diretamente para a equipe e, assim, analisamos, fornecemos os prazos, desenvolvemos e realizamos os testes unitários
  • A equipe de desenvolvimento não compreendeu a vontade do cliente: Em outras vezes, o desenvolvedor não conseguiu compreender bem os requisitos. Quanto mais cedo a falha na interpretação for detectada, menos custo vai gerar. A capacidade de interpretação deve ser uma preocupação do desenvolvedor. Se algo não foi bem entendido, não deixe o momento da reunião passar. Alguns minutos a mais utilizados durante o levantamento dos requisitos, podem significar menos horas ou até dias durante o processo de desenvolvimento. Obviamente, não estou falando de nenhuma metodologia ágil, como a XP, que prevê a participação efetiva de alguém do negócio durante o desenvolvimento;
  • O cliente não sabe o que quer: Acontece com frequência. Entretanto, o nosso papel como consultor, na minha visão, também consiste em ajudar nesse sentido. Traduzir uma chuva de idéias em algo sistemático. Devemos conseguir enxergar os processos repetitivos e automatiza-los. Normalmente o cliente não sabe (e nem tem a obrigação de saber) como as coisas se comportarão quando os requisitos sairem do papel e virarem sistema. O cliente entende do negócio dele e sabe, melhor do que qualquer um, o que vai agregar valor. O desenvolvedor deve ter a perspicácia de encontrar a real necessidade daquele que o contrata. O conhecimento técnico de quem está solicitando o sistema é, normalmente, muito vago.
Salta aos olhos o motivo raiz (root cause) dos três motivos que citei acima: comunicação.

Nesse sentido, a ubiquitous language (linguagem ubíqua), trazida a tona pelo DDD (Domain Driven Design), exerce um papel fundamental.

A princípio, o que seria uma linguagem ubíqua? Ubíqua, segundo o Aurélio, significa:
adj. Que está ao mesmo tempo em toda parte. (Sin.: onipresente.).
Trazendo para a nossa área, é uma linguagem dominada tanto pelo cliente quanto pela equipe de desenvolvimento. Desenvolveremos a questão da ubiquitous language e a DDD em posts futuros. No momento, basta sabermos que existe uma forma de melhorar a comunicação com o cliente.

Sem uma boa comunicação, é difícil conseguirmos um bom sistema. É comum em nossa área, termos profissionais com certa dificuldade para se expressar e para entender o que está sendo discutido. Esse problema é, normalmente, causado, pela timidez e dificuldade de concentração. Entretanto, existe uma luz no fim do túnel. Existem treinamentos para resolver essas dificuldades.

A timidez é oposta à segurança. Quanto mais seguro você está sobre um assunto, menos tímido você se sentirá para aborda-lo. Assim, alguns passos para acontecer a mágica da mudança de comportamento é:
  • Estude muito: quanto maior for o seu domínio sobre determinado assunto, maior será a sua segurança de falar sobre ele. Não estude apenas a teoria, mas também, crie cenários onde a teoria possa ser exercitada;
  • Não falar de algo que você não entenda bem: Esse é outro ponto importante. Se você está inseguro sobre determinado assunto, não fale nada. Escute e tente absorver o máximo de conceitos que está sendo debatido por outras pessoas. Se a sua idéia sobre determinado assunto não estiver completamente formada, não opine;
  • Aprenda a ser contrariado: quem nunca foi contrariado, nunca opinou. No nosso dia a dia, nos deparamos com situações que dependem da nossa avaliação e do nosso ponto de vista. Entretanto, outras pessoas podem ter um ponto de vista melhor devido a, por exemplo, ter mais experiência na área ou na empresa. Devemos nos preparar para sermos contrariados. Se não nos prepararmos quanto a isso, vamos correr o risco de gerar transtornos psicológicos que farão nos omitirmos cada vez mais.
Os pontos levantados ajudam na melhora da comunicação. Melhorando a comunicação, as reuniões com os clientes fluem com mais naturalidade e, consequentemente, mais fácil será o levantamento de requisitos.

Parte I - Introdução
Parte III - Design por contrato
Parte IV - Flexibilidade
Parte V - A Lei de Demeter
Parte VI - Eficiência
Parte VII - Coesão
Parte VIII - Usabilidade
Parte IX - Relacionamento entre classes

quinta-feira, 7 de maio de 2009

[OFF-SERIES] Opinião sobre o livro do Braude

Uma das coisas mais sensacionais de estar mantendo um blog, é a possibilidade constante de reciclagem de conhecimento. Quem não quer escrever muita besteira, vai dar uma olhada, inclusive, em obras que já leu.

Isso aconteceu no dia 05/05/2009, quando me preparava para escrever a primeira parte dos princípios de projeto de software, com o livro Software Design: From Programming to Architecture do Eric J. Braude. Quando reli a parte que fala sobre correção e robustez, encontrei tantas falhas que não acredito que não tenha visto na época da leitura.

Após uma breve reflexão, percebi dois motivos:
  1. Na época que li a obra, não tinha lido nem um terço dos artigos que li até hoje, isto é, meu conhecimento era mais limitado;
  2. Este livro, foi a primeira obra que li sobre engenharia de software. Fiz uma analogia interessante: Quando visitamos um belo lugar pela primeira vez, não percebemos todos os detalhes do local. Na segunda vez que vamos, percebemos mais detalhes. Na terceira, já percebemos os buracos na rua, os prédios que eram históricos passam a ser velhos, etc. Dessa forma, não percebi alguns erros sutis na obra do Braude. Erros esses que me frustaram bastante.
O primeiro erro que considerei relevante foi que Braude, no título que aborda os princípios de correção e robustez, cita a legibilidade, mas nada escreve no desenvolvimento do tópico.

Outro erro, foi ele mencionar na introdução dos princípios citados no parágrafo anterior que existe uma sutil diferença entre correção e suficiência, dizendo que mostraria mais a frente, mas isso não acontece.

Outra falha foi mencionar a refatoração para a correção. Se não atendermos a correção (cumprimento dos requisitos), não teremos aplicação. Se um determinado módulo não atende o requisito para o qual ele foi (está sendo) construído, não teremos uma refatoração, mas continuaremos a construção. Estranho perceber como ele não desenvolve o assunto no corpo do tópico.

Eu sei... eu sei... que devemos comprar obras de autores reconhecidos e, de preferência, recomendados. Eu sei disso... hoje em dia. Sem contar que, na época que comprei, eu não conhecia a trilha de livros do Shoes.

Entretanto, continuo usando essa obra como uma das referências dos princípios de um bom projeto de software. Simplesmente, tenho adaptado as partes onde discordo do autor.

Baseado nessas constatações, não poderei mais recomendar o livro. A partir de hoje, ele sumirá da minha lista de livros recomendados.

terça-feira, 5 de maio de 2009

Princípios de projeto - Parte I

Falaremos agora de correção e robustez.

Aqui, a palavra correção, é utilizada para traduzir correctness, representando a qualidade do que é correto.

Sintetizando em uma frase, correção é o atendimento dos requisitos pela sua aplicação; robustez é a capacidade do seu sistema em lidar, de forma correta, com as exceções.

Estes princípios são obrigatórios. Sem eles não existe aplicação. Na teoria, isso é simples de ver, enquanto, na prática, não é tão simples assim. Existem alguns motivos para o projeto falhar na correção, e serão mostrados no próximo post.

Quanto mais simples e direta a pergunta, mais simples e direta será a resposta. Entretanto, é com requisitos complexos e confusos que, normalmente, trabalhamos. O cliente, não nos chama para resolver dois mais dois.

Normalmente, para implementar um determinado requisito, dispomos de
n formas. Assim, para sabermos qual a forma correta, precisamos recorrer aos outros princípios de projeto de software. Por hora, isso não nos interessa.

Podemos usar invariantes para garantir os valores de entrada. Essa é, inclusive, a razão de viver dos métodos de atribuição: setters.

Mas o que são invariantes? Segundo Page-Jones:
É uma condição que todo objeto de uma determinada classe deve satisfazer, por todo seu ciclo de vida (quando o objeto estiver em equilibrio).
Objeto em equilíbrio é o objeto que não está em transição de estado.
Também temos as pré e pós-condições, que atuam a nível das operações. Ex: MENOR_DATA <= nascimento <= MAIOR_DATA. Lembrando que eliminamos números mágicos, portanto não interessa, para quem estiver implementando, os valores das constantes MENOR_DATA e MAIOR_DATA. Em termos gerais, esses valores, fazem parte das regras de negócio do cliente. Mas e a correção no comportamento? Este tipo é bem coberto pelos Testes Unitários. Com eles, descobrimos se a lógica está fazendo o que deveria fazer. Existe um excelente artigo sobre o JUnit aqui. Outro excelente artigo, este sobre mock objects. Montando uma suíte de testes, teremos muito mais segurança ao executar refatorações e atender as Change Requests.

O tratamento de exceções é outra forma de garantia de robustez. E o primeiro aspecto que deve ser observado é: nunca lance uma Exception. Se você está tratanto de alguma exceção, saiba o que está sendo tratado. O tempo é curto, mas isso é ponto chave na aplicação. Saiba, ao certo, que tipo de exceção aquele trecho de código pode lançar e trate-a. Todos nós, desenvolvedores, seremos um pouco mais felizes.

É válido notar que, os testes podem passar e mesmo assim a robustez não estará totalmente garantida. A suíte não é responsável por testar determinadas situações, como queda do banco. Enquanto o banco está no ar, os testes rodam. E quando cair? Vai despejar um stack trace na tela do cliente? Claro que não.

A robustez é uma das variáveis que fornecerá os dados para medir a confiabilidade do seu sistema. Outras variáveis são a arquitetura de hardware, S.O. e a rede. A confiabilidade é obtida através de qtd de falhas / unidade de tempo.

Uma falha na rede pode, facilmente, ser tratada na sua aplicação, mostrando uma mensagem de erro agradável (se é que podemos unir erro e agradável na mesma frase) para o usuário. Falhas e/ou baxa perfomance de hardware ou S.O. é mais complicado de resolver no código.

Podemos prever problemas de perfomance, pensando na eficácia do código. Entretanto, estaremos sempre limitados ao(s) hardware(s), ao S.O. e à rede. Se uma base de dados
tunada, estiver em um Pentium 100 MMX, com 64mb de memória, em uma rede de 10Mbits, sua aplicação CRUD pode estar em um supercomputador, com código eficaz e, mesmo assim, deixará a desejar na perfomance.

É necessário buscar o equilíbrio correto entre essas quatro variáveis principais, equilibrando, também, com uma variável importante para o cliente: o custo.


No próximo post, discutiremos alguns dos fatores que levam a falha do princípio da correção no processo de software.


Parte II - Correção
Parte III - Design por contrato
Parte IV - Flexibilidade
Parte V - A Lei de Demeter
Parte VI - Eficiência
Parte VII - Coesão
Parte VIII - Usabilidade
Parte IX - Relacionamento entre classes