Uma nova edificação

Por esta hora – quase um mês depois do meu ultimo post – alguns podem estar pensando o que tenho andado a fazer.

Quando criei este blog lá em 2007 era para ser apenas um lugar onde pudesse escrever sobre os meus gostos – que são muitos e variados. O “problema“ é que rapidamente o gosto maior tomou conta: o Java.

Eu escolhi me especializar em Java, em tudo o que diz respeito a Java, por razões profissionais, mas se tornou um hobby muito interessante ao ponto de me fazer criar o MiddleHeaven. Através do Java aprendi sobre Orientação a Objetos e mesmo sem os purismos de Smalltak o estreito mapeamento entre a linguagem Java e os conceito de Orientação a Objetos concorrem para que quanto mais se conheça um, mais se aprecie o outro.

Hoje, o meu blog é visitado por milhares de pessoas todos os meses que procuram se educar um pouco mais nestas coisas e aprender a criar aplicações Java melhores, fugir de más práticas e aprender melhores formas de codificar e mapear o mundo real para objetos. Muitos defendem a visão empirista em que através de tentativa e erro se chega a um modelo bom e uma aplicação robusta. O experimentalista em mim  entende essa visão, mas o arquiteto em mim prefere ter menos trabalho criando um modelo mais duradouro. O desafio é grande, mas a recompensa será maior.

Só que, há um problema com esta visão. Os consumidores de software coorporativo, ao contrário dos consumidores caseiros, não sabem o que procurar em um software, não sabem avaliar a sua qualidade. E o pior é que nem os desenvolvedores sabem avaliar essa qualidade. Ela é intangível, imensurável. Contudo, ela não é subjetiva. Existe sim o bom e o mau. O Padrão e o Anti-Padrão, o crédito e o débito técnico.  O problema que eu vejo é que tanto desenvolvedores, quanto os donos de empresas que produzem software, quanto os consumidores desse software adoram gastar rios de dinheiro e ampulhetas de tempo em gambiarra, mas não dão o braço a torcer para procurar qualidade, diminuição de custo, mais-valia. A culpa do débito técnico sobre a recompensa do crédito técnico. Sentimento de utilidade para quem compra e sentimento de orgulho para quem vende.

É por isso que no ultimo mês coloquei na prática os alicerces de uma idéia que há muito estava na minha cabeça. São os primeiros tijolos para um espaço que levará as pessoas a produzir melhor software de forma mais barata, sem gambiarra, sem prejuízo para a saúde mental, emocional ou moral de ninguém e que os cliente sintam vontade de usar e evoluir.  Um portal que ajude a explicar o que é um produto software, como se faz e por que se faz assim. Tecnologias, Práticas, Regras, Teorias, Tutoriais e, espero, muitos exemplos rodando no seu navegador e no seu desktop que comprovem  que isto é possível e ajudem a enterrar as velhas práticas da Era da Pedra ( do cartão ? ) da produção de software como um bem.

Este empreendimento é maior que eu. É maior que um só blog. É necessário um lugar  com mais recuros e menos limitativo que estas fronteiras, onde esta ideia possa ser discutida, aperfeiçoada, exemplificada. É um novo edifício. Hoje ainda com poucos cômodos, mas que logo crescerá. O céu é o limite. A nova casa para o desenvolvimento de aplicações com Java: www.javabuilding.com

Fantochada

Dom Quixote lutava contra moinhos de vento. Muitos programadores estão lutando contra fantoches.  Generalizou-se a ideia de que objetos sem métodos outros que não modificadores (set) e acessores (get) são ruins porque são sempre manipulados por outros objetos: são fantoches.

Ora, esta ideia, em si mesma é que é a grande fantochada. Alguns objetos são simplesmente um saco de propriedades e não há nada que possamos fazer contra isso. Embutir artificialmente métodos nesses objetos só para que pareça que eles fazem alguma coisa é simplesmente errado. Ao tentar fugir dos fantoches criam-se monstros piores.

O Principio de Separação de Responsabilidade pede que cada objeto tenha apenas uma responsabilidade. Se a responsabilidade do objeto é apenas ser um saco de propriedades, então que seja. Exigir dele mais do que isso é violar o Principio de Separação de Responsabilidade por querer colocar no objeto coisas que ele não sabe fazer ou não pode fazer.

Um  exemplo clássico do que estou falando é o objeto Usuario. Muitos gostam de colocar um mudarSenha(String senhaAntiga,  String senhaNova). Já vi isto várias vezes. Dois erros:

  1. Porque precisa da senha antiga? O usuário já tem um getSenha que é esse valor. O argumento é que o usuário real tem que saber a senha atual e portanto senhaAntiga tem que bater com o valor em getSenha(). E o que acontece quando não base certo? Lança exception? E se eu não quiser fazer isso?
    Conclusão: é uma decisão que pode ter várias estratégias conforme quem decide, quando e onde. Não ha uma resposta possivel única. Logo, isso deve ser isolado em outro objeto.
  2. Quem muda a senha do usuário? A aplicação. Certo? Não é o próprio usuário que realmente muda a senha. É sempre alguém que o faz por ele. Esse alguem não é o usuário, logo, isso não é responsabilidade da classe usuário. É responsabilidade de um outro agente do sistema, outro objeto.

Outro é o uso do pseudo-ActiveRecord. Por alguma razão que me escapa ao entendimento muitos acham que  ter um método save() no proprio objeto que está sendo guardado, é  uma excelente ideia.  Pode até ser, se for bem implementado. Isso é a essência do padrão ActiveRecord. Só que o ActiveRecord tem contra indicações. Ele não é recomendado para sistemas grandes. Certo. Agora vai dizer que o seu sistema não é grande e portanto você pode usar o ActiveRecord. O sistema pode parecer pequeno agora, mas deixe passar um tempo e verá. ActiveRecord é bom para protótipos que vão – com certeza – ser jogados no lixo. Mas aceitemos que para o seu caso ActiveRecord é uma boa ideia; ai ,muita gente faz assim :


public class ObjectQualquer {

DAO daoObjectoQqualquer;

public void save(){
daoObjectoQualquer.save(this);
}
}

Não vou nem entrar no mérito se deve usar DAO ou Repositorio (para ActiveRecord é DAO mesmo) mas esse código é o exemplo de como é fácil associar responsabilidades aos objetos que eles não têm. Como sei isso? Porque o objeto simplesmente delega a outro. Sem alterar nada, sem produzir nenhum outro efeito. Depois vêm perguntar: “Como injeto o DAO neste objeto?” a resposta é “Porque raios você tem esse objeto ai para começo de conversa?!” É muito difícil chama o DAO apenas quando ele é necessário? Que raio de preguiça é essa?

Não é perguiça. É a falsa noção de que os objetos têm que ter métodos diferentes de get/set. E ai as coisas mais absurdas são feitas para atingir esse objetivo.

Um objecto é composto por três coisas: estado, comportamento e responsabilidade. Responsabilidade é o que os outros objetos esperam que ele faça. Comportamento é como esses objetos pedem que isso seja feito e estado é a forma que o objeto tem de “memorizar” o que fez.

A responsabilidade deve ser apenas uma. Isso é obvio. Quanto mesmos responsabilidade mais simples é o objeto. Lembre-se disto. O comportamento é um contrato publico. É algo do tipo : “quando chamarem por  desta maneira farei este trabalho, desta forma.” Isto não necessariamente significa que existe um método especifico que traduz o comportamento, mas sim que ha um contrato que é acessível por meio de um método. Por exemplo, ArrayList e CopyOnWriteArrayList têm comportamentos diferentes, embora as sua interface (o conjunto de métodos) seja a mesma.

Ao definir um objeto primeiro você define a sua responsabilidade: “Este é o objeto que é responsável por … “, depois como ele vai possibilitar essa responsabildiade. Só quando você o implementa é que você precisa de pensar no estado do objeto.

Mas e os objetos cuja responsabilidade é apenas portar dados? O comportamento deles é dar acesso aos dados e o estado deles são os dados (ou representações dos dados).

Tomemos como exemplo o objeto String. Ele porta dados (caracteres) e tem estado (um array de char) que representa esses dados.  Pronto. Preciso colocar um save() nele só porque ele vai ser gravado em banco de dados? Não. A responsabilidade de String é muito simples: portar caracteres. String é talvez o objeto mais manipulado em Java. Isso, com certeza, não faz dele um objeto fantoche. Então porque o meu TipoProduto que só contém uma String com o nome do tipo e um inteiro com um código para o tipo é um fantoche ? Não é.

Todo este delirio quixotesco de ver objetos fantoche onde só existem objetos simples e incólumes advém de um má interpretação daquilo que significa “comportamento” em um objeto. A mensagem original é muito simples e se prende com outra caracteristica do design orientado a objetos : inversão de controle.  A ideia é o seguinte : não deixe para os outros o que você pode fazer. Um objeto string pode informar quantos caracteres guarda. Isso é trivial, porquê delegar isso a outro objeto? Um objeto String pode informar qual é o caracter que está na posição n da cadeia. Por que delegar isso a outro objeto?

Existem comportamentos que são naturalmente associáveis com a responsabilidade do objeto e por isso o objeto ganha essas sub-responsabilidades. Isto é feito , não porque o Principio de Separação de Responsabilidade é fraco, mas sim porque ele é forte. Se deixassemos outro objeto nos informar de, por exemplo, o tamanho da String, teriamos um objeto com um metodo  objectoX.length(String s). Quando um objeto Y precisasses saber o tamnho da String ele teria que chamar X. Isso cria um acomplamento artificial entre X e Y. Então , atribuindo a responsabilidade ao String esse acoplamento não existe mais. Contudo, isto não significa que os métodos sempre devem ser transportados para o objeto que contém os dados.  O comportamento do método têm que ser natural à responsabilidade principal do objeto.

Um contra exemplo para mostrar isto é o objeto Date. Ele contém uma data. Se eu quiser saber a idade de uma pessoa eu preciso saber a data do seu nascimento. A primeira aproximação seria fazer calculaIdade(Date dataPessoa) e seguindo o exemplo atrás você poderia ser tentado a fazer dataPessoa.calculaIdade(). Ai você bateria de frente com o fato do Java não lhe permitir criar métodos novos em classes existentes e a sua conclusão seria que java é uma porcaria de linguagem e você migraria para ruby onde isso é possível.  Coitado do Java. Na realidade é você que é um péssimo designer. A idade é da Pessoa e não da data de nascimento. O método seria calculaIdade(Pessoa pessoa). E pessoa tem um atributo público que informa a data de nascimento. Claro que a idade é algo que depende de quando fazemos a pergunta. Então precisamos de mais uma informação que é a data atual: calculaIdade(Pessoa pessoa, Date atual)

Utilizando o método acima poderiamos pensar em fazer Pessoa.calculaIdade(Date atual). Seria isso certo? Pessoas podem calcular as suas idades?  Podem.

Animais não sabem calcular as suas idades. Significa isso que Cao.calculaIdade(Date atual) é errado? Não.
Por muito que você goste de abstrair o mundo em objetos e o princípio de separação de reponsabilidade tenha que ser cumprido, ele se aplica a Objectos e não a coisas do mundo. Então, embora um cão não saiba calcular a sua idade, o objecto Cao não É o cão. Ele é uma abstração humana daquilo que um cão É. Portanto, o objeto pode conter responsabilidades que um humano entenderia para o objeto e não as responsabilidades que o ente real, realmente tem. Ou seja, em termos simples: um objeto pode ter mais responsabilidades/comportamentos  que a sua contraparte real.

A mensagem é que diminua ao máximo o acoplamento atribuindo comportamentos naturais aos objetos que já tem no seu modelo. Sim, poderiamos pensar que um comportamento como “capitalize” (coloca todos os caracteres do principio das palavras em maiuscula) é um comportamento natural de um String. E ai você irá xingar o Java de novo por não lhe permitir adicionar esse comportamento. Mas será mesmo que é isso?

Não será que na realidade isso seria o comportamento esperado para um Texto? Ou mais especificamente ainda, para um Titulo? Qual é a diferença entre formatar um data para um String com certo padrão e formater um String para outra String com um certo padrão. Não será que na realidade Capitalize é a responsabilidade de um objeto de formatação?

Não existe uma única resposta para um design. É por isso que se chama design (desenho). Cada um descreve de uma forma. E sim, existe a corrente do Realismos (os objetos são as coisas), do Impressionismo (os objetos parecem as coisas) e até do Cubismo (todos os objetos são cúbicos). Da designer tem o seu estilo, e se funciona não está muito mal. Só que um design não “corre”. Ele funciona abstratamente e não no CPU. Um design que funciona (que é funcional) é aquele com baixa manutenção. E baixa manutenção envolve várias coisas além de gosto artistico por um estilo. Envolve decidir e fazer trade-off de muitas coisas simultaneamente. Se você não tem um estilo artistico de design, pelo menos conheça e use as tecnicas dos designers profissionais.

A proliferação de objetos do tipo bean (apenas como get/set) não é uma questão  derivada de mau design. Ela acontece porque esta é a forma padronizada que criar objectos que são sacos de propriedades (PropertyBag). Muitas outras formas existiriam: como usar Map ou criar uma classe PropertyBag. Contudo, classes genéricas como essas tirariam poder de abstração que é tão importante e pior que isso, tirariam tipagem forte. Repare que fazer bean.getNome() é muito mais forte e refactorável que propertyBag.get(“nome”). O uso de Strings é desaconselhado e por isso o uso de beans é tão comum. Contudo, sempre que o bean puder provêr comportamente extra que lhe seja natural, deve fazê-lo e não delegar isso para outro objeto (normalmente apenas com métodos estáticos). A palavra chave é puder. Às vezes ele quer, e até parece natural, mas ele não pode.

Não há problema nenhum em que um objeto só seja um bean com os seus get/set se isso é realmente o que ele deve ser. O problema real é você ter objetos (classes) apenas com métodos estáticos que fazem operações sobre objetos que um deles poderia fazer sozinho. Essa delegação excessiva é que é realmente o problema, ou colocar sempre os get/set sem pensar se é esse o comportamento esperado/necessário daquele objeto.

Não lutemos então contra fantoches  ou fantasmas anoréxicos que só existem na nossa cabeça.  Alguns objetos são realmente simples e com uma só responsabilidade e poucos comportamentos. Tão poucos que a única grande responsabilidade é guardar dados e prover acesso a essa memória.

Java é o próximo C

Muita comoção tem rolado por ai sobre como a linguagem Java será substituída por outras, especialmente as linguagens que estão entrando na JVM.

Acho que muita gente não entendeu que o J em JVM significa Java. O que quero dizer com isto é que a JVM foi feita para correr Java. Ok, ela foi feita para correr Java Bytecode, mas no fim existe uma estreita relação entre a linguagem Java, o bytecode e a JVM.

Muitos dos avanços da plataforma desde a versão 1.5 vieram da generalidade do bytecode face à linguagem que por exemplo, aceita coisas como herança múltipla que a linguagem não aceita. Mas muitos outros vieram de truques de compilação em que o compilador aceita sintaxes diferentes e as compila para o mesmo bytecode de sempre.

As novas linguagens da JVM como Groovy e Scala desenvolveram compiladores que compilam para o mesmo bytecode mas devido à falta de alguns construtos na JVM estas linguagens precisam usar de alguma magia para que tudo funcione perfeitamente.

Pois bem, a solução óbvia é incrementar a JVM e o bytecode com novos construtos necessários a estas linguagens : invocação dinâmica, tail call, continuations, etc..

O ponto é que, devido à estreita relação entre a JVM e a linguagem Java , o Java tem a oportunidade de absorver estas novas capacidades. É claro que mesmo a JVM as tendo a linguagem não é obrigada a ter, mas não há razão para que não possa. Tudo parece se resumir a gostos políticos e a indecisão às interjeições que estão acontecendo com a venda da Sun à Oracle.

O futuro da JVM é bem claro. Ela tem que evoluir para suportar mais linguagens que Java. É o mesmo tipo de evolução da VM .NET cuja tecnologia não está nem perto da JVM mas suporta várias linguagens.

O futuro da linguagem Java pode não incluir modificações a curto prazo, mas não há razão para não o fazer e várias para fazer. A razão principal para as fazer é tornar a linguagem Java a como a linguagem base para JVM da mesma forma que o C é a base para as máquinas não-virtuais.  Da mesma forma que o Java e outras linguagens utilizam o C para comunicar com máquina real, linguagens na plataforma java utilizarão o Java para comunicar com a JVM.  Tudo isto de forma tão encapsulada quanto a comunicação do Java com a JVM.

O Java 7 pode conter um monte de pequenos acertos na linguagem escrita que se compilarão para o mesmo bytecode. Açucar sintático (sintax sugar) é como se chama a isto. Coisas como inferência de tipos genéricos em declarações ou acesso a listas como a sintaxe de arrays. Tudo isto interessante e desenhado para minimizar a escrita pelo programador. Contudo acertos no nivem baixo serão poucos. A invocação dinâmica que estará presente – ao que tudo indica – não será suficiente a longo prazo, mas já quebra o galho de muitas as linguagens da JVM como Groovy.

O precisamos entender é que Java sempre estará presente mesmo quando outras linguagens tomarem o pódio na JVM. Se, por exemplo, Scala, se tornar a linguagem mais utilizada sobre a JVM, ainda assim o pessoal que implementa,  e especialmente que estende essa linguagem, terá que o fazer usando Java. Java passa assim a ser a linguagem de baixo nível que a JVM aceita como par. É como a Common Language Runtime do .NET ou o C da programação para máquinas físicas. É o esperanto da JVM que todas as novas linguagens terão que saber falar.

Esta realidade não apenas significa que o Java não está morto, como o seu uso será cada vez mais especializado. Enquanto a maioria dos mortais usa Scala, Groovy , Fortress ou outra linguagem sobre a JVM, extensões serão feitas nessas linguagens por uma minoria programando em Java. Além disso novas linguagens serão criadas com Java sobre a JVM.

O uso do Java pelas massas poderá diminuir  tal como C diminuiu, e outras linguagens mais produtivas virão. Mas Java continuará lá sendo o C da JVM , sendo o C para das novas linguagens. Você poderá fugir de utilizar java no dia a dia, mas não poderá dizer que java morreu da mesma forma que hoje a JVM existe porque é construída com C.

Dito de outra forma, você pode escolher outra linguagem e abandonar a linguagem Java, mas não poderá fugir de usar a JVM e toda a plataforma que já existe.

Uma ótima apresentação pelo Niel Gafter chega , eu acho, nesta mesma conclusão.

Como epílogo podemos concluir que utilizar alguma plataforma fora JVM é um risco. As grandes apostas e os grandes apostadores  estão sobre o Java. Se a Oracle não pisar na bola, continuará assim. Do outro lado, temos cada um apostando no seu cavalo e isso não poderá chegar perto da evolução da JVM a curto prazo. Utilizar linguagens fora da JVM  é um risco e até linguagens como PHP , Pytohn e Ruby estão vindo para a JVM. É uma questão de tempo até que as funcionalidades dessas linguagem vazem para a linguagem Java.

E você acha que é programador?

Escrever software implica comunicar a uma máquina as intenções de um ser humano. Para qualquer comunicação é necessário um conjunto de símbolos que ambas as partes reconhecem e entendem. O problema com as máquinas de hoje é que elas entendem um número limitado de símbolos, muito menor que o dos humanos.

Para resolver isso, vários paradigmas foram criados buscando transmitir à máquina as intenções do ser humano. O mais vantajoso até hoje é o paradigma da linguagem de programação.

Programar significa utilizar uma certa linguagem para transmitir uma série de instruções ao computador. O ser humano escreve com símbolos que ele entende – palavras e símbolos textuais – e isso é transformado para o símbolos que a máquina entende através de um programa chamado compilador. Sim, você pensou certo. Se o compilador é um software, e um software é criado com um compilador, como se criou o primeiro compilador?

Parece uma charada mas não é. Acontece que existem diferentes níveis de linguagem. Linguagens de alto nível e de nível máquina ( “baixo nível” não se diz porque é feio). Os primeiros compiladores eram escritos em linguagens de nível máquina com os quais se criaram compiladores de nível mais alto e assim sucessivamente até linguagens de alto nivel como Java, C++ ou C#. O paradigma orientado a objetos é atualmente o paradigma das linguagens mais flexível e difundido, já que nele é possivel montar linguagens com outros paradigmas (procedural, funcional, etc) sem perda de generalidade.

Bom, temos uma linguagem. Toda a linguagem escrita tem um semântica e uma sintaxe. As de programação também têm. E toda a escrita é redigida por alguém.  No mundo editorial quem escreve é redator, mas no mundo do software, quem escreve para máquinas é programador. O texto que o programador escreve é chamado “código” (alguns chamam de código fonte, do inglês “source code“) para transmitir a ideia que é meio críptico e muito “secreto”.

Mas então qualquer um que escreve código é um programador? Tecnicamente sim, mas na realidade isso não diz muito sobre o que a pessoa faz ou sabe fazer. É como dizer que todos os autores de best sellers sabem escrever. Isso é verdade, mas não significa nada de útil. É uma tautologia se pensarmos bem.

O que é interessante para o mundo do software não é que a pessoa saiba escreve código,  o interessante é que a pessoa escreva bom código. Da mesma forma que autores escrevem bons livros. Para isso é preciso uma capacidade técnica maior que simplesmente escrever palavras. O programador é para o código o que um autor é para um livro e não apenas um redator. Bom, pelo menos um (bom) programador aspira a ser um autor e não um redator.

Da mesma forma que na língua portuguesa também nas linguagens de programação uma instrução pode ser escrita de várias formas. Umas mais claras que outras. E enquanto qualquer frase minimamente representativa da ideia basta para a pessoa comum, não basta para o autor que quer tirar o maior partido das palavras que pode usar para escrever em menos espaço o maior número de ideias. Mas também existe um limite. Ser conciso demais pode levar à confusão do leitor médio. Um autor não escreve para si, escreve para  os demais, para ser lido, já que o objetivo ultimo é vender livros difundir as suas ideias.

O programador sofre do mesmo problema. A linguagem até pode permitir que ele escreva mais em menos palavras, mas nem sempre isso é a melhor forma para quem lê. A variedade C de linguagens é conhecida por permitir uma ampla gama de formas de escrita – bastante crípticas, por sinal. E Java permite que tudo seja escrito usando códigos Unicode como \u0002 … Lá porque você escreve dessa forma, não significa que o deva. Essa é a diferença entre um autor e um redator. Essa é a diferença entre um escritor de código e um programador.

Mas saber escrever não é apenas colocar palavras juntas. Existe mais. Existe conhecer as palavras em si mesmas, as regras da linguagem (como escrever corretamente) e  conhecer a semântica da linguagem (o que as palavras significam). Para programadores isso significa saber o que cada palavra reservada faz, assim como as bibliotecas padrão que acompanham a linguagem.  Estas bibliotecas são como dicionários de palavras novas que podem ser (re)utilizadas a cada momento para enriquecer o texto.

Muitas linguagens, poucas palavras

Quando você aprende a falar e a escrever, normalmente, você aprende a língua de seus educadores, que por extensão é a língua do seu país. A sua língua natural. Também quando você programa você começa por aprender uma linguagem. A diferença é que essa, ainda não é, a sua linguagem natural.

Durante a vida do programador ele aprende muitas linguagens da mesma forma que aprendemos muita línguas. Afinal, traduções são limitadas, em si mesmas, na riqueza de transmitir o pensamento (as instruções) do autor, e ler o original, na lingua originalmente pensada para transmitir a mensagem, é sempre uma experiência mais rica. O programador passa por um tempo de busca da sua linguagem natural. Aquela que ele entende e é proficiente sem esforço. Imagine um prêmio nobel da literatura escrevendo em outra língua que não a sua.  Não é simples atingir o mesmo nível de intimidade com todas a linguagens. O programador descobre isso com o tempo.

Pensemos que você decide aprender todas as línguas faladas na Europa. Parece simples. Você até é capaz de agradecer e perguntar as horas em todas elas, mas você consegue manter uma conversa longa em todas elas. sem parecer um idiota?

Parecer um nativo é impossível. Você tem que ser um nativo para falar e escrever nativamente.  É um erro a pessoa pensar que pode aprender uma lingua/gem por tradução daquela que já conhece. Isso dá para o básico, não para o avançado, muito menos para o extraordinário.

Assim, quantas mais linguagens, menos palavras. Em termos de software, você pode conhecer muitas linguagens e fazer o básico em todas elas, mas só será proficiente em algumas e só será intimo com uma ou duas. É uma regra natural, seu cérebro não aguenta saber tudo todo o tempo.

O programador tem então três caminhos. Ser um autor memorável em uma linguagem, ser um “zé-ninguém” em todas ou ser um “meia-boca” em meia dúzia.

Profissionalmente você não ganhará bom dinheiro sendo autor memorável em uma linguagem nem “zé-ninguém” em todas. Você ganhará dinheiro sendo proeficiente em uma ou duas e se desenvolver com uma ou duas (o que é desenvolver é assunto para outro post). Ou seja, você acaba deixando de ser autor no meio do caminho para passar a ser editor, revisor,  professor ou dono de uma editora. É uma mudança de carreira, mas uma necessária nos dias de hoje (um pequeno segredo: ninguém quer realmente pagar para alguém escrever código bem. O mercado, hoje, está preocupado em escrever depressa. Não bem.)

O programador pode evoluir em amplitude ou em profundidade, mas não em ambos. É demasiado extenuante. O “problema” é que para evoluir ele precisa aprender pelo menos uma linguagem em profundidade.

Bom, então se o caminho profissional natural do programador é deixar de ser programador,  se ele se dispersa em várias linguagens, nunca será ninguem no mundo do software ?  Sim. Se você ficar perseguindo linguagens novas todos os dias acabará acordando – tarde – para o fato que não está em lugar algum. Como o andarilho que percorre e conhece todos os caminhos, mas  não onde voltar depois da caminhada. Pelo contrário, se você seguir uma ou duas linguagens, você atingirá o nível necessário para passar ao próximo nivel: desenvolvedor.

Não há vergonha nenhuma em você ser um bom programador em duas linguagens e excelente em uma delas.  Aliás, deveria se sentir dignificado com isso, já que é raro.  Mas é como o cara que saber fazer contas de cabeça com 1000 algarismos e de trás para frente: assombroso, mas ninguém pagará você para fazer isso. (Bom, quase ninguém. Se você for louco talentoso o suficiente para fazer isso, alguem pagará.)

Quando uma pessoa é inciada no mundo do software espera-se que saiba programar. O famoso “programador júnior”. O que ele sabe é escrever código. Não programar. Porque normalmente ele não entende o que escreve e não escreve coisa intelegível. Mesmo que funcione, ele não sabe por onde começar na hora de alterar ou re-escrever em outro lugar. É natural. Afinal todos tivemos que saber o alfabeto antes de saber escrever o nosso nome. O problema é que com tantas linguagens por aí é fácil a pessoa se frustrar e constantemente mudar de rumo. Saberá muitas linguagens, mas saberá dizer pouco.

Se você se apresenta como programador,  pergunte-se: eu sei realmente escrever bem? Os outros entendem meu código sem eu explicar? Estou seguindo as regras? Sei escolher as instruções e API certas ?

Sem saber , você pode ser um “zé-ninguém” em todas as linguagens ou um “meia-boca” na meia duzia com que se cruzou até hoje. E você, ainda, acha que é programador?

De Sênior a Gerente

Se você é desenvolvedor a algum tempo com certeza já se deparou com a questão da promoção de sênior a gerente. Por algumas razões que iremos analisar as pessoas não só aceitam este fato como esperam por ele.

Não é incomum durante uma entrevista perguntar para o candidato a uma vaga de desenvolvedor onde ele se vê daqui a 5 – 10 anos, e a resposta costuma ser “como gerente”. A razão para isso é simples: dinheiro. Historicamente a pessoa na posição de Gerente ganha mais que a pessoa na posição de desenvolvedor, seja qual for a sua classificação ou maturidade. Mas esse, espante-se, não é o único fator. A chamada da sereia do poder é prazerosa.

As empresas acham que promover a pessoa de desenvolvedor sênior para gerente é uma coisa boa. Não é. E as pessoas na sua extrema visão curta só enxergam essa opção.  Não é segredo que todos queremos ganhar mais, então quando a pessoa diz que quer ser gerente o que ele está dizendo, na verdade, é que quer mais dinheiro. Nesse ponto eu desclassifico o candidato já que ele ainda não deixou de ser júnior e já quer ficar mandando nos outros.

Por razões que o tempo conhece as empresas se habituaram a pensar que criar software é dificil e que a probabilidade do projeto de software dar errado é grande. Portanto, os diretores que não querem ver o seu na reta adotam a política de: 1) por um lado criar bodes expiatórios na pessoa do gerente. Se o projeto der errado eles serão culpabilizados e o diretor manterá o seu emprego; 2) é preciso microcontrolar tudo o que os desenvolvedores fazem para que assim não existam imprevistos e não existam atrasos.

O curioso é que são exatamente essas medidas de “contingência” que fazem o projeto atrasar.

O resultado é que em uma hierarquia de um diretor de produção de software é comum existirem vários “gerentes”, os quais tentam microcontrolar a equipe de desenvolvimento. A pessoa no papel de gerente  rapidamente  sacrifica os membros  da equipe para manter um salário um pouco melhor que eles sendo que ele seria incapaz de realizar o mesmo trabalho. A imagem do feitor de escravos me vem à mente.  O pior de tudo nem sequer é isso. O pior de tudo é que, normalmente, a pessoa na posição de gerente não tem capacidade técnica nem política para desempenhar esse papel. Sim, a pessoa foi desenvolvedor sênior 20 anos atrás. Isso não lhe dá conhecimento nenhum sobre como o software é feito hoje.  Não apenas a linguagem e o paradigma utilizado hoje são diferentes, como também as técnicas e ferramentas em volta (uso de repositório de código, por exemplo). Quanto mais cedo a pessoa passou de sênior a gerente mais óbvio é este fato, no limite absurdo de comparar, por exemplo, a plataforma Java com linguagens como Clipper, Delphi ou VisualBasic. Você já reparou como o seu gerente reduz tudo a operações no banco de dados e desconhece o conceito de “Servidor de Aplicação” ou o confunde com “servidor web” ?

Quanto à parte política, a pessoa na posição de gerente não tem qualquer escruplo ou vergonha em pedir ao desenvolvedor para trabalhar extra para manter o (famoso) cronograma. Mas  peraí! Não é o gerente que criou o cronograma? Se houver atraso não é responsabilidade dele? Infelizmente no mundo atual não. Nada nunca é responsabilidade do gerente e ele faz de tudo para que assim não seja. O clássico é pedir que os desenvolvedores estimem o cronograma. Ele pede que “estimem” mas o que ele quer dizer é “assinem com sangue um chute de quanto tempo vai ser necessário”. Depois o gerente faz a seguinte conta: se a “estimativa” é X então como temos N desenvolvedores vai demorar X/N tempo. A estimativa … quer dizer, a corda no pescoço da equipe de escra… desenvolvedores ficou ainda mais apertada. Nestas condições totalmente indecentes a equipa tem zero motivação , zero ajuda, zero autoridade, total responsabilidade e lá para quando faltarem dois meses para o final do prazo do cronograma fajuto a equipa ainda passa a ser chicoteada diariamente com a pergunta “Quantos porcento falta para estar pronto?”. O que revela que a pessoa no lugar de gerente não sabe o estado das coisas, ou seja, ela esteve fazendo o quê enquanto os desenvolvedores criavam o software? Esperaria-se que estivesse exatamente calculando quanto tempo falta. Certo ?

O diretor (a pessoa hierarquicamente acima do gerente e que o contratou como bode expiatório profissional) não se preocupa com a performance do gerente. Apenas com a da equipe. Afinal todos os males advém da equipe de desenvolvedores. Esses seres abjetos que o diretor é obrigado a tolerar para poder vender alguma coisa a alguém. Ao diretor tanto lhe faz se o gerente explora os desenvolvedores da mesma forma que o senhor lhe importa um pepino que o feitor chicoteie os seus escravos. Não só isso, como o diretor espera que o gerente aja assim.  Tanto isso é verdade que em empresas maiores (leia-se “com mais níveis de isolamento dos seres abjetos da equipe”) existem uma camada de gerentes. O diretor delega para N gerentes, cada um deles delega para M outros gerentes, que delegam a outros … em um cadeia até que se chega no gerente que controla a equipe. Vejam bem o estado da coisa. O gerente não serve para gerenciar o projeto. Não. Isso é fácil, qualquer excel ou project pode fazer isso. O gerente serve para controlar a equipe em uma mistura de babysiter com capataz e a empresa é tanto maior quanto mais gerentes forem controlados por outros gerentes.

Quantos “gerentes” estão acima de si na sua empresa? Dito de outra forma, quantas pessoas podem vir chateá-lo na sua mesa com exigências para ontem ?

Parece então óbvio porque um desenvolvedor quer virar gerente: 1) mais dinheiro no fim do mês; 2) menor ou nenhuma responsabilidade sobre o projeto ou o software; 3) direitos de fustigar a equipe como e quanto quiser; 4) receber todos os louros dos superiores quando o projeto dá certo; e 5) nunca ser “castigado” por nada.

Parece muito melhor que a vida de um desenvolvedor que 1) ganha pouco para aquilo que faz e a responsabilidade que tem; 2) tem toda a responsabilidade sobre o resultado mas nenhum autoridade para guiar o processo; 3) é interrompido a todo o momento com perguntas idiotas que não são da sua responsabilidade responder como “Quantos porcento do projeto já está completo?” 4) nunca recebe o agradecimento real de ninguém nem o reconhecimento real do esforço (eu disse real e não aquele tapinha nas costas ou aquele e-mail de agradecimento modelo B) e 5) é sempre “castigado” por tudo no limite de ser despedido por justa causa por erros cometidos pelo gerente, pelo diretor ou até pelo erro estratégico da empresa como um todo.

Se você teve estômago para ler até aqui, parabéns. Vejamos agora um pouco do outro lado. Afinal, nem todo o mundo é mentecapto e alguma pessoas querem realmente ganhar dinheiro a sério e não apenas para pagar as contas. Qualquer economista, por muito ruim que seja, sabe que uma forma de ganhar mais é gastar menos. É fácil gastar menos com desenvolvimento de software.

Primeiro, foque no que dá dinheiro. No caso do software o que dá dinheiro é o software, funcional e entregue. Muito importante o entregue. Segundo, desenvolvedores são pessoas com educação superior e qualificadas a resolver problemas lógicos e matemáticos complexos. Não os trate como animais de curral. Converse com eles e ouça o que eles dizem. Melhor que ninguém eles sabem quais são os problemas com o software. E ninguém melhor que ele sabe como traduzir o que é esperado pelo mercado em código. Eles podem ajudá-lo não apenas a resolver problemas técnicos mas até problemas que impactaram na venda do software ou na aceitação pelo público. O seu foco é fazer software, então dê recursos aos desenvolvedores para o fazerem. O foco da empresa é o software e todos devem ajudar a conseguir que ele seja feito nas melhores condições de mercado possíveis.  Simplifique os processos. Coloque no lixo a hierarquia militar de passar ordens entre níveis.  Muita informação se perde dessa forma quando o assunto é complexo como um software. Pode até funcionar para a guerra onde as ordens são simples, mas não numa empresa de software.  Uma muito boa forma de conseguir isto com facilidade, sem gastar dinheiro e com um retorno imediato é substituir todos os que se dizem gerentes por desenvolvedores sênior (realmente sênior e não apenas júniors disfarçados). Implementar Scrum também não é má ideia, mas se você tem um outro processo que realmente funciona para a sua empresa (eu disse, realmente – o que significa que todo o mundo na empresa acha que funciona) então mantenha esse.

Implemente um mecanismo de carreira. Não separe os desenvolvedores por anos de trabalho  e sim preveja que todos têm mais do que uma habilidade. Não é desmérito para ninguém saber programar bem. Saber escrever código limpo, bem estruturado, que aproveita ao máximo as funcionalidades da linguagem não é pecado. Nem todos têm  de ser arquitetos. Não é desmérito para ninguém ser um bom tester que sabe escrever testes automáticos com boa cobertura.

A vida de um desenvolvedor têm várias partes e não são: júnior , sênior, gerente. São: programador, engenheiro,  tester, designer, analista e arquiteto. E isto não é uma sequência. Cada um pode ser mais do que uma coisa. Aliás tem que ser mais do que uma. Existe o básico que é ser programador (saber programar não é suficiente) e existe o complexo: analise é uma tarefa ao mesmo tempo técnica, interpessoal e até política onde poucos engenheiros e arquitetos se sentem bem. Moral da história, monte uma equipe multidisciplinar sem gerentes fustigadores mas com pessoas que ajudem a resolver os problemas políticos, burocráticos e administrativos e deixe o desenvolvimento com quem entende.

A próxima década não terá pena de quem não se ajustar à nova ordem. Quem ainda quiser ficar fuçando no código como se fazia à 20 ou 30 anos atrás não vai chegar a lado nenhum diferente da falência. A concorrência é maior que nunca e o mercado de tecnologia é maior do que nunca. Quem não primar pela qualidade não vai vingar.

A escravatura das fábricas de software tem que acabar. O primeiro passo é que você, desenvolvedor,  não aceite esses termos.  Aspire a ter capacidades de análise, conhecimento de arquitetura, design ou teste, e não a ser um gerente mentecapto e escravocrata.  Afinal, você gostaria que pensassem de si o que você pensa do seu gerente?

De Júnior a Sênior

Vivemos uma época transformadora no desenvolvimento de software . A partir da segunda década do século XXI só vai sobreviver quem fizer software barato (leia-se: sem “gordura”),  recheado de valor, feito com responsabilidade e entregue no prazo. É a hora de separar o trigo do joio.

Os sufixos júnior e sênior me aborrecem enormemente desde sempre. Especialmente quando utilizados fora de contexto ou como sinônimos de “tempo de serviço”. Mas o que realmente faz de você um júnior ou um sênior?

A resposta a esta pergunta pode não ser o que você esperava ouvir. Mas se quiser trabalhar com software nos próximos decênios é bom que a aceite.

A diferença entre júnior e sênior não está na idade, nem no tempo de serviço. Está na maturidade técnica e na maturidade profissional.

Para um júnior, trabalhar muito é sinônimo de “bom”. Trabalhar até altas horas e acumular um monte de horas extra é um sinal de dignidade. Para um sênior só de isso ser sugerido, é um insulto. O sênior sabe que se algo der errado não é com horas a mais ou fins de semana longe da família que o problema se resolve. Bem pelo contrário. Se agrava. Então a posição do sênior é não ter problemas. Para isso ele usa todos os seus skills técnicos para que problemas não aconteçam ou sejam facilmente mitigados. Um bom design, uma bateria de testes automatizados e muito refactoring são ferramentas básicas do sênior para não deixar “a vaca ir p’ro brejo”.

Para um júnior, boas práticas são subjetivas e discutíveis e gambiarra é um martelinho de ouro que resolve todos os problemas com uma pancada só. Para o sênior, as boas práticas são como leis da natureza, objetivas e irrevogáveis, e a gambiarra um pecado demoniaco intolerável que tem ser exorcizado a qualquer custo de todo aquele de quem se apodera. O sênior sabe que seguir bons princípios e boas práticas fazem as coisas fluirem mais facilmente e responder mais eficazmente a imprevistos enquanto o júnior ignora que as suas gambiarras são aquilo que está fazendo seus fins de semana serem perdidos na empresa ao invés de poder estar em casa ou em passeio com os amigos ou a namorada.

O júnior acha que o objetivo de construir um software é fazer o programa funcionar. O sênior sabe que o objetivo de criar um software é fazer uma aplicação de fácil manutenção. Pois é na manutenção que está o custo e não na criação.

O júnior acha que com 3 anos de serviço pode ser um pleno. Um pleno tapado será se pensa que o tempo traz experiencia. O trabalho é que traz experiencia. O sênior sabe que desenvolver software é uma arte e uma arte não se aprende com o tempo e sim com a prática.

O júnior tende a usar pouco a cabeça, tentando seguir ao máximo “receitas de bolo”, sem se ater ao contexto. O sênior racionaliza o problema e encontra a solução mais flexível até à solução. Normalmente esta solução só é possível com o uso de alguma técnica avançada de desenvolvimento de software como o uso de  objetos  em vez de rotinas. Como para o júnior boas práticas são piadas que se contam aos amigos este tipo de técnica passa longe.

O júnior fica feliz quando o dinheiro entra na conta todo o mês, o sênior dorme tranquilo quando sabe que o código que a sua equipe fez tem qualidade e pode ser mostrado a qualquer um.  Bom, nisso o junior é muito semelhante. Ele também não tem nenhuma vergonha do código que escreve. Acontece apenas que ele não a tem porque não enxerga as tremendas burrices que o seu código exclama.

Maturidade profissional não se ganha com o tempo. É preciso que a pessoa tenha orgulho no que faz e prime pela qualidade do que faz. Só isso a fará se aprefeiçoar.

Se você acha que ainda é júnior, não se desespere, aprimore-se. Acredite que as boas práticas são realmente boas e apreenda-as. Use-as. Tenha orgulho do que faz e vergonha dos seus erros. Procure qualidade e não quantidade. Procure terminar antes do prazo e com mais funcionalidades e não se faça de preguiçoso para poder arrecadar algumas horas extra. Seja profissional. Desconfie de qualquer um que o tentar levar pelo mau caminho.

Se você conhece alguém nas condições descritas aqui como júnior que ocupa um cargo sênior não tenha medo nem vergonha em o desafiar. Tanto tecnica como profissionalmente. Teste-o. Ele pode estar enganando você. E se você é diretor de gerentes de TI, a probabilidade de estar sendo enganado por um júnior se passando por gerente é quadriplicada. Cuidado, abra os olhos.

Se você é um sênior, tal como descrito aqui, meus parabéns. Agora é hora de elevar a qualidade exigindo mais dos que estão à sua volta. Ou dobra ou parte. Não há meio termo. O seculo XXI não terá pena de quem for conivente com a mediocridade.

Scrum

Um dia todos usarão Scrum e tirarão um bom sarro das metadologias obcuras e cabalisticas que se usam por ai hoje em dia.

Até lá é preciso difundir as práticas e teorias do Scrum. Desmitificar um pouco esse novo. Afinal muito se escrever por ai sem pés nem cabeça. Uns dizem que o Scrum é baseado no manifesto agil ou que é um processo de desenvolvimento de software. Ouve-se e lê-se muita coisa ridicula por aí.

A verdade é que Scrum é uma tecnica de gerenciamento de Projetos que visam entregar Produtos. Isto cai que nem uma luva para projetos de software mas muitos outros tipos de projetos podem usar esta tecnica.

Tendo isto em mente  e continuando a exploração do conceito de que criar software  é uma arte,  abro hoje uma nova secção do meu blog dedicada ao Scrum e a disseminar as simples e poderosas ideias que ele trás.

O Scrum  é ótimo para pequenas equipes e empresas que estão dandos os primeiros passos. Ao cortar a burucracia e aproximar o cliente o Scrum traz-lhe um ROI mais rápido para poder alavancar a sua empresa mais rápidamente mas fundá-la em pilares sólidos para o futuro.

Se conhece comente. Se não conhece experimente.

Sistema pequeno. Mente pequena ?

Existe uma moda de falar em sistema pequenos. “Posso fazer xxxxx ? é para um sistema pequeno.” , ” se eu fizer xxxxx tudo bem, certo? é apenas um sistema pequeno” – todos já ouvimos isto e até alguns já podem ter dito. Normalmente xxxxx é alguma gambiarra.Do tipo, posso fazer meu sistema apenas com métodos estáticos ? é um sistema pequeno.

Para mim isto é uma falácia do pensamento. Não existe sistema pequeno. O sistema pode nascer pequeno – modesto em funcionalidades – mas ele tende a evoluir. Mais cedo ou mais tarde esse sistema irá precisa de manutenção (leia-se corrigir algum problema ou aumentar as suas funcionalidades). Com a manutenção o sistema irá crescer.

Esta lógica leva-me a crer que quando alguem diz “sistema pequeno” está pensando em “sistema fast-food para enganar trouxa”, ou seja, “vou fazer esta porcaria, vender por uma nota e ganhar uma nota. Se o cara me processar depois, eu não vou estar mais aqui”. Este tipo de pensamento é triste. Mostra que ha muitos mercenários por ai que não têm qualquer honra no trabalho que fazem e tudo o que querem é dinheiro. Software, infelizmente, não dá dinheiro. Boas ideias dão dinheiro. Boas execuções dão dinheiro.

Será então que quem pensa em sistemas pequenos tem a vista curta ? Que não pensa a longo prazo ?  Este tipo pensamento pode-nos levar por um longo caminho de asneiras. Por exemplo, se o sistema é “pequeno” porquê construir camadas ? porque isolar componentes ? porquê escolher frameworks e tecnologias que trabalham bem juntas? porquê seguir boas práticas ? aliás, porquê aprender boas práticas ? porque investir aprendendo Orientação a Objetos ? porquê levantar requisitos ? porquê sequer fazer direito quando pode fazer rápido ?

Uma outra face desta moeda furada é o comum “vamos fazer só assim, e depois a gente vê como faz o resto”. Basicamente, traduzindo, significa “vamos fazer um sistema ‘pequeno’ e depois o aumentaremos”. Mas o que é pequeno aqui é a visão. Visão curta. Pensar grande corta tempo e custos porque se pensa em todas a partes. Não ha imprevisto nem surpresas. Podemos componentizar as coisas e deixar alguns componentes com implementações mais simples do que gostaríamos – mais simples, não mais “pequena”.

Aliado ao tamanho “pequeno” temos o intervalo de tempo “pequeno”. Frases como “vamos fazer um sistema pequeno para vender logo” ; leia-se : “vamos produzir um porcaria qualquer só para por no mercado sem pensar como isso afeta a nossa imagem , aumenta o risco e produz custos não estimados e altos”.

Os Romanos pensaram grande quando disseram “vamos conquistar o mundo”. E para isso criaram um estrutura social completa, infraestrutura. Infraestrutura sem a qual não seria possível conquistar nada nem ninguém. Criaram estratégias pontuais para alcançarem o objetivo maior.

Não pense pequeno. Aprenda a pensar grande. Aprenda a dividir para conquistar. Para isso nunca abra mão da qualidade do software que produz. É o seu nome, a sua dignidade, a sua honra que está nisso. Eleve a qualidade do código/software que lhe chega em mãos. Não tenha medo se defender a bandeira da qualidade. Se alguem não gostar, tenha a certeza que são eles que estão errados.

E sei que temos que comer e para isso precisamos trabalhar. E para trabalhar precisamos engolir alguns sapos de vez em quando. Mas existe um limite moral até onde você pode ir. A partir daí é trabalho intelectual forçado, é escravatura intelectual, é prostituição intelectual.

Mercenários pensam pequeno e ganham dinheiro, mas são infelizes e mal vistos pela sua falta de moral. Ninguém confia neles.  Artistas pensam grande e são normalmente felizes e as pessoas tendem a confiar neles.  Tudo bem que ha artistas que nada ganham e outros que ganham muito. Isso depende do talento de cada um. Não apenas do talento artístico como do comercial, interpessoal, etc..

Embora possa parecer que pensar pequeno pode ser uma vantagem a curto prazo, nunca é uma vantagem a longo prazo. E sendo que sistemas sempre duram além da sua vida útil, o longo prazo mal planejado tende a ser um problema.

Você pode pensar grande e dar passos simples , um de cada vez e chegar no que pensou. Mas ao pensar pequeno por muito que corra nunca vai chegar onde deveria. Isso porque você não sabe onde deveria chegar. Porque não pensou nisso antes ?

Nosso novo blog

Já era hora, eu achei, de criar um novo blog para falar do MiddleHeaven.

Tenho dedicado meu muito escasso tempo livre a este projeto durantes os últimos anos e está na hora de o mostrar ao mundo (e ser criticado por isso …).

O blog em inglês não deslanchou e o site feito pelo maven é pesado para atualizar. A ideias são muito mais fluidas e, contando que a minha equipe jornalística sou eu mesmo é bem mais facil utilizar um blog. A volta ao blog do WordPress em deterimento do Blogstop é que o Wrodpress apresenta a muito útil capacidade de criar páginas estáticas além do blog.

Convido a todos a conhecerem o nosso novo blog para entender e desenvolver o MiddleHeaven.

A seu tempo vou colocar nele os textos já apresentados, em inglês, no blog antigo.
Espero que acabe havendo algum cross-siting entre os dois blogs especialmente em referências a padrões e coisas relacionadas ao Java em si. Isso não era possível com o blog antigo devido à diferença da língua. Espero que isso, também, seja uma vantagem.

Aproveito para informar o estado do projeto. Embora já seja possível criar telas swing e sites jsp ainda falta um pouco para que as peças principais estejam no lugar.  Recentemente integrei o NeoDatis e parece bastante promissor, contudo, leva a uma revisao do modelo de dominio baseado em anotações (sem ORM , não ha necessidade das anotações). Por outro lado, revisei o mecanismo de wiring (injeção automática) para ser possível encontrar pontos de injeção por outras vias que não annotações. Desta forma é possível análises mais dinâmicas. O mecanismo de persistência é o próximo a ser revisto. Espero que após isso uma versão do framework possa ser usada para aplicações web simples (a la Spring / Struts / Vraptor / Mentawai) .

Claro que, para isso, você precisa estar preparado para não usar o Hibernate… será que aguenta ? 😉

Os 10 Mandamentos do Programador Java

Programar em Java pode ser uma experiencia muito rica e gratificante, sobretudo quando construímos programas elegantes – que com poucas linhas fazem muitas coisas.

Nem sempre é fácil manter qualidade no código, sobretudo quando muitas mãos mexem nele.

Uma forma de obter qualidade é que toda a equipe siga um padrão de codificação comum, mas isso não é suficiente se nem todos seguem as regras básicas para a programação em Java.

A nova página “Os 10 Mandamentos do Programador Java” pode ajudar a ter algum nível de coerência no código da sua equipe.

Para mais controle considere utilizar uma ferramenta como o CheckStyle ou o PMD. Para saber mais sobre o assunto leia “Effective Java” , especialmente a segunda edição que dá dicas para o uso dos novos recursos do java 1.5 e 1.6