Programadores Java ou Ratos ? 

Jun/10
18

N√£o sei se felizmente ou infelizmente mas a API java n√£o d√° suporte a algunas coisas que s√£o bem comuns no desenvolvimento de software. Algumas ele at√© suporta, mas as pessoas n√£o usam direito. Quando se constroi um sistema do zero, algumas coisas precisam ser desenvolvidas simplesmente porque n√£o ha nenhuma biblioteca que as tenha, e mesmo se houvese, n√£o as teria exactamente como precisamos. Ent√£o equipas afoitas que querem logo come√ßar a debitar entreguas esquecem-se deste pequeno promenor e n√£o dispendem o tempo e o estudo necess√°rio relativamente a estes detalhes. Depois o que acontece ? Acontece que como o design n√£o coopera com a realidade, as gambiarras come√ßam a acontecer. E todos sabemos onde isso nos leva… Ent√£o ha que ter cuidado com estes impulsos…

Tiny Types

Não ha muita documentação sobre isto, porque é bastante trivial e se aprende nas primeiras páginas de qualquer livro sobre orientação a objetos : Classifique os conceitos. Ou seja, crie classes para os conceitos. Classes não são artefactos que permitem reaproveita código, elas são artefactos que nos permitem classificar o codigo, da mesma forma que os biologos classificam os seres vivos usando uma classificação em reinos, filos, etc, até as  espécies.

Apenas uma pessoa sem no√ß√£o lhe dir√° que exista tal coisa como “classes demais” .. acaso existem conceitos “demais” ? Podem existir conceitos que n√£o cabem no contexto, mas n√£o conceitos demais. N√£o se poupe de criar classes , por muito simples que pare√ßa.

Java é fortemente tipado e existe uma muito boa razão porque as linguagens de propósito geral são fortementes tipadas : permitem melhor classificar conceitos e por consequência melhor polimorfismo. Use isso em sua vantagem.

Crie tipos especiais para todos os tipos de dado, objeto, conceito , etc… que n√£o forem suportados pelos tipos b√°sicos do Java. CPF n√£o √© um numero, n√£o √© um texto, √© um c√≥digo. N√£o existe uma classe Code no java. Crie um objeto CPF, Telefone, etc…e se quiser at√© um objeto Number e Text. Afinal o number do java n√£o tem opera√ß√Ķes aritm√©ticas b√°sicas como somar e subtrair.

A aritm√©tica computacional de ponto flutuante √© mais complexa do que explicam na escola. N√£o confie nela. Use objetos especiais para fra√ß√Ķes, taxas e sobre tudo para dinheiro. Mesmos que seja apenas para uma moeda e apenas para encapsular um BigDecimal ( mas , na real, implemente o padr√£o Money sem BigDecimal), mas sempre crie um tipo especifico para representar dinheiro.

Datas e Tempos

Aprenda a usar Date e Calendar, mas n√£o os use diretamente. Crie tipos especializados. Crie objetos de intervalo, muito uteis, mas inexistentes em java. Use uma API como o Joda-Time (no futuro use a API de Date & Time do java) , ou crie a sua, mas criar uma API de tempos e datas n√£o √© trivial, voc√™ precisa ter muito conhecimento de como funcionam os mecanismo. Nunca , nunca, use Calendar como um atributo de uma entidade. Isso √© o equivalente a vc usar um objeto Calculadora em vez de Integer.Use Date ou um objeto que fa√ßa o mesmo que Date, ou seja, nada. √Č um objeto que cont√©m um long que √© o numero de milesegundos desde 1 de janeiro de 1970. Apenas isso.

Não assuma que trabalhar com tempos de datas é facil. Não cometa o erro muito básico de fazer as contas você mesmo. Nunca faça isso. Delege  a Calendar ou a uma API especilizada como o Joda-Time. Nunca faça calculos do tipo o mês tem 30*24h ou assuma que uma hora sempre têm3600 segundos e um dia tem sempre 24 horas. Crie objetos para representar a duração e o periodo independentemente. Investigue até você saber a diferença entre estes dois.

Date e Calendar não dão suporte a dias uteis que é uma demanda comum em sistema, portanto você terá que implementar essas lógicas. Não é simples. A definição de dia util depende do negócio. Nem sempre o Domingo é uma folga. Feriados normalmente são lidos de um banco. Tenha isso em atenção.

Monte uma estrutura e reuse-a. Não se contente com o simples, faça-a robusta e reutilizável em mais do que um sistema. Use muitos cenários e mantenha muitos testes. Faça-a exacta, não um tapa-buraco.

Tratamento de Exce√ß√Ķes

Tratamento correto de exce√ß√Ķes tem regras. Force-as. Tome aten√ß√£o √† camada onde a exce√ß√£o ser√° lan√ßada, e de onde, na camada, o ser√°. Entenda o conceito de exce√ß√£o, e sobretudo a diferen√ßa pr√°tica entre exce√ß√Ķes verificadas e n√£o verificadas. Siga boas pr√°ticas de tratamento de exce√ß√Ķes como se a sua vida dependense disso. Ela realmente depende. Ok, talvez n√£o a sua vida. Mas as a sua sa√ļde mental com certeza.

N√£o tente criar uma hirarquia “auxiliar” de exce√ß√Ķes. N√£o fa√ßa suas exce√ß√Ķes muito espertas, mas fa√ßa-as informativas. Enrique√ßa-as com parametros. FileNotFound – qual file ? ClassCastException ? qual classe ? N√£o use mensagens hardcoded. Use chaves de mensagem e um sistema deresource bundle para a tradu√ß√£o (ver internacionaliza√ß√£o).¬† E nunca, nunca, pelo que lhe for¬† mais sagrado,¬† mate um stacktrace. Se vc n√£o sabe o que isto signfica, ent√£o v√° estudar mais. Voc√™ n√£o est√° preparado para trabalhar com java e muito menos para criar um sistema do zero.

Internacionalização

N√£o confunda Internacionaliza√ß√£o (i8n) com Localiza√ß√£o (L10n). Internacionaliza√ß√£o significa : “Nenhuma informa√ß√£o que seja passivel de ser diferentes entre culturas √© hardcoded”. Localiza√ß√£o sgnifica : “Fa√ßa todas as informa√ß√Ķes passives de serem diferentes entre culturas sejam especificas e coerentes com a cultura X, por agora”.
Não cometa a o erro de  achar que internacionalização é sobre traduzir textos. Nem pense que  não faz falta se o sistema apenas será usado em uma cultura.

Repare que eu disse cultura, e não Locale. Cultura não muda apenas entre paises e linguas. Pode mudar entre empresas e négocios e até mesmo entre departamentos da mesma empresa.

Aprenda a usar os recursos do pacote java.text como DateFormat, NumberFormat e MessageFormat. Aventure-se a criar a sua API de globalização (que soma as ferramentas para internacionalização com de localização). Crie uma convenção de nomenclatura para as chaves das mensagens. Faça-a hierarquica separando os niveis com ponto ,por exemplo: label.cliente.nome
Nunca escreva codigo de convers√£o de String para data ou de String para numero, etc… use formatadores. Crie formatadores para os seus tiny types. Formata√ß√Ķes s√£o et√©rias, dados s√£o eternos.

Mas internacionaliza√ß√£o n√£o √© apenas uma quest√£o de estilo. O seu sistema trabalha com endere√ßos ? Ele aceita endere√ßos no estrangeiro ? Imagine se Amazon n√£o aceitasse endere√ßos no estrangeiro…
O seu sistema segue padr√Ķes internacionais ISO para pesos e medidas ? Ou √© como a sonda NASA que faz metade no sistema m√©trico e metade no sistema de libras ? O seu sistema trabalha com dinheiro? v√°rias moedas¬† ? como vc grava no banco ? com duas casas decimais ? E as moedas que n√£o t√™m casas decimais ? E as que t√™m mais¬† de 2 casas ? Voc√™ grava datas no seu banco de dados ? Em qual fuso hor√°rio ? O seu banco suporta diferentes fusos hor√°rios ? Seu sistema √© um site ? Ele atende v√°rios paises ? qual √© o encoding das suas p√°ginas ? N√£o √© UTF-8 ?

Sempre que vir o requisitos “Este sistema deve ser internacionalizado” trema de medo, porque v√™m muita coisa ai. N√£o assuma que √© simples, nem f√°cil, nem barato.

Validação

Valida√ß√£o n√£o √© o mesmo que consist√™ncia. Consist√™ncia¬† : garantir que o objeto n√£o tem um estado impossivel.¬† Por exemplo, 30 de fevereiro √© inconsistence. Valida√ß√£o √© verificar que um objeto consistente, √© us√°vel pelas regras da aplica√ß√£o/neg√≥cio.¬† Use uma API de valida√ß√£o. De preferencia fa√ßa a sua mesma. √Č um bom exercicio de OO. Inspire-se em bibliotecas que j√° existem como a Apache Validator ou a JGodies Validations. Tem a JSR de Beans Validation, d√™ uma olhada tamb√©m… qui√ßa fa√ßa parte do futuro do java.

Modificadores ( vulgo, setters) não fazem validação. Eles fazem consistência !

Pesquisas

Entenda que a parte que importa de um sistema de dados √© pesquisa. Tenha uma API preparada para isso. N√£o foque apenas no CRUD, lembre-se que existem relat√≥rios e existe importa√ß√£o/exporta√ß√£o de dados.¬† Fa√ßa um sistema orientado a dominio. √Č mais simples, mas tenha cuidado de n√£o abusar ou confiar demais em ORM. JDBC funciona muito bem, obrigado.

Use um sistema de Critérios+Intrepretador. Mesmo se usar o Hibernate. Não crie critérios do Hibernate diretamente. Isso ajudará a manter uma API de critérios que faz oq ue você quer mesmo que o Hibernate ou o JPA não façam. Nesses casos você apela para estratégias alternativas.

N√£o assuma que suas tabelas t√™m poucos dados e nunca precisar√° pagin√°-los ou carregar mais de 10 mil registros de um s√≥ vez. Vco√™ precisar√°. Os dados acumulam-se. Tenha isso em conta desde o inicio. Use padr√Ķes como Fastlane Reader para ler muitos dados .

N√£o menospreze o poder do banco de dados de fazer calculos agregados (somas, m√©dias, etc…) aproveite-se disso para aumentar a performance, mas nunca √† custa de viola√ß√£o de camadas.

Se est√° com pressa use o Hibernate como motor das pesquisas, mas fa√ßa uma casca em torno dele. Ele n√£o √© perefeito e voc√™ ter√° que limar algumas arestas. Aprenda a mexer com Hibernate. N√£o √© simples. Ele √© bastante complexo , mas o abandone √† primeira.Se tem tempo, crie sua propria API. √Č ainda mais complexo do que fazer o hibernate e o risco √© brutal, mas o aprendizado √© grande … fa√ßa voc√™ olhar o hibernate com outros olhos .. mesmo com todas as suas falhas.

Desista de usar like para pesquisas textuais do tipo que vemos em sites de e-comerce. Aprenda a usar o Lucene.  Melhore a experiencia dos usuários.

TagLibs e TagFiles

Use-os. N√£o use tags de terceiros. √Č tentador, mas voc√™ cai no vendor lock-in que nem um patinho ( ou ser√° como um “bobinho” ?).¬† Sobretudo tags relacionadas a internacionaliza√ß√£o e acesso. Proiba todo e qualquer uso de scripts ( excepto, talvez, em tag files). Use tag files para coisas que dependem de css ou da estruura gr√°fica do sistema em si e taglibs ( o nome correto √© tag handler, mas todo o mundo conhece como taglib) para coias mais gerais, at√© para coisas que mais do que um sistema poderia usar ( como o controle de acesso).

Não use includes ( se tiver que usar use a tag jsp:include e não a diretiva include). Use frameworks como o sitemesh ou o tiles  , ou desenvolva seu mecanismo. Mais uma vez, não é trivial, portanto se você não sabe, use uma API canónica. Não invente muito, use JSP e nada de velocity ou freemarker ou essas outras tecnologias de renderização. Nem sequer xml+xslt (jsp pode escrever xml também, sabia ?).

Se usa JS F ignore a parte de jsp e taglibs, mas n√£o ignore o problema de usar componentes de terceiros.

Epilogo

Sim. √Č complexo. Muita coisa para come√ßar uma aplica√ß√£o decente, mas somos programadores java ou ratos ?

7 comentários para “Programadores Java ou Ratos ?”

  1. Muito bom o post, parabéns! Mostra umas verdades muito importantes que o pessoal deveria saber mas muitas vezes não sabe.

    Discordo talvez só da ideia de abandonar o Hibernate na primeira oportunidade. Acho que dá pra ser feliz com ele fazendo tudo bem encapsulado como você disse.

    E sou grande f√£ tamb√©m de JSPs com meus pr√≥prios tagfiles ūüôā

  2. Bom artigo Sergio,

    sobre a parte de aprender Hibernate (ou algum outro ORM) a fundo, tbm é legal ler o PoEAA, tem tudo muito bem mastigadinho lá.

    Outro ponto formidável é a sua diferenciação entre i18n e l10n, pra falar a verdade, é raríssimo alguém que conheça esses conceitos bem, e é importante diferenciá-los.

    Parabéns.

  3. Muito bom o artigo. São atitudes simples que todo bom programador precisaria ter, mas como a presa é inimiga da perfeição, deixamos de lado certos princípios que poderiam nos ajudar muito num futuro próximo. Parabéns!

  4. Ol√° !

    Muitos avisos interessantes para os marinheiros de primeira viagem ou mesmo relaxados no desenvolvimento, mas n√£o concordo onde vc instrui √† construir novos frameworks de tratamento de datas, ou validadores,etc… Hoje em dia, √© muito dif√≠cil n√£o encontrar algo pronto e maduro que n√£o sirva para vc.
    O maior problema que encontro nos projetos que passo, é exatamente os desenvolvedores fazerem seus próprios frameworks, incluir essas horas durante o desenvolvimento e não entregar nada de valor para o cliente e culpar o Java como sendo uma linguagem de desenvolvimento lenta.
    Construir esses frameworks para tecnologias mais comuns, deixe para fazer em casa, em sess√Ķes de Dojos, pq no trabalho o que faz um cara bom √© entregar software de valor para o cliente.

    []’s

  5. Excelente artigo. Direto ao ponto e realmente recheado de dicas importantes.

  6. A mensagem que deve ser entendida n√£o √© “fa√ßa seu pr√≥prio framework”, porque isso √© dificil. Sobretudo no assunto datas e tempos. Sempre que possivel use frameworks j√° prontos. Eu mencioneio o Joda-Time, Apache Validation e o Hibernate, por exemplo. A mensagem √© “n√£o use frameworks de terceiros diretamente” , tente sempre encapsul√°-los numa API sua. Isto porque eles sendo bons , n√£o s√£o perfeitos , e alguns s√£o bem trabalhosos (o JFreechart por exemplo) , alguns fazem coisas que n√£o s√£o intuitivas, como o Hibernate. Ent√£o, uma API sua, sempre pode ser usada para limar essas arestas.

  7. Fantástico artigo, parabéns mesmo. Poucas coisas não concordei, beeeeeeem poucas coisas.

Comente

Artigos