segunda-feira, 11 de novembro de 2013

Apague o seu código para torná-lo melhor

Menos é mais. Essa é uma máxima um pouco banal, mas as vezes é verdadeira. Uma das melhorias que tenho feito em nossa base de código nos últimos anos tem sido remover pedaços dela.
Escrevemos o software seguindo dogmas de XP, incluindo YAGNI (que quer dizer, You Aren’t Gonna Need It, Você Não Vai Precisar Disso). Mas sendo nossa natureza humana como é, inevitavelmente somos fracos em alguns pontos.
Observei que o produto estava levando muito tempo para executar certas tarefas, tarefas simples que deveria ser quase instantâneas. Isso por que estavam sobre-implementadas – enfeitada com firulas que não eram necessárias, mas que naquele momento pareciam ser uma boa ideia.
Então simplifiquei o código, melhorei sua performance, e reduzi o nível de entropia global do código simplesmente removendo as funcionalidades desnecessárias da base de código. Prestativamente, meus testes unitários me disseram que eu não havia quebrado nada durante essa operação. Uma experiência simples e plenamente satisfatória.
Mas por que o código desnecessário acabou lá em primeiro lugar? Por que um programador sentiu a necessidade de escrevê-lo, e como isso passou pelos processos de revisão de código e programação em pares? Quase certamente algo do tipo:
- Era um coisa legal de se escrever e o programador queria escrevê-la. (Dica: Escreva código porque agrega valor, não porque você que agrada);
- Alguém imaginou que isso seria necessário no futuro, então sentiu que seria melhor escrever isso já agora. (Dica: Isso não é. YAGNI. Se você não precisa disso agora, não escreva isso agora);
- Não parecia que o “extra” era tão grande assim, então seria mais fácil implementar isso agora do que ir até o cliente para ver se isso era realmente necessário. (Dica: Sempre leva mais tempo escrever e manter código extra. E o cliente na verdade é bem acessível. Uma pequena porção de código extra vira uma bola de neve com o tempo e se torna uma grande porção de código a ser mantido);
- O programador inventou requisitos extras que não estavam nem documentados nem discutidos para justificar a funcionalidade extra. O requisito era na verdade falso. (Dica: Programadores não definem requisitos, o cliente define);
No que você está trabalhando agora? Isso é realmente necessário?
Pete Goodliffe
97 Things Every Programmer Should Know: Collective Wisdom from the Experts, Kevlin Henney, O'Reilly Media, Fevereiro de 2010, pág. 78

segunda-feira, 4 de novembro de 2013

Aprendizado Contínuo

Vivemos em tempos interessantes. À medida que o desenvolvimento é distribuído pelo mundo, percebemos que há muitas pessoas capazes de fazer o nosso trabalho. É preciso continuar aprendendo para se manter no mercado. Caso contrário, nos tornamos dinossauros, presos no mesmo trabalho, até que, um dia, deixamos de ser necessários ou temos nosso trabalho terceirizado para uma fonte mais barata de recursos.
Sendo assim, o que fazer a respeito? Alguns empregadores são generosos o suficiente para fornecer treinando para ampliar nosso conjunto de habilidades. Outros podem não ser capazes de dispor do tempo ou dinheiro para nos oferecer qualquer formação. Por segurança, precisamos assumir a responsabilidade sobre nossa própria educação.
Aqui está uma lista de dicas de como se manter atualizado. Muitas destas podem ser obtidas de graça na Internet:
• Leia livros, revistas, blogs, feeds do Twitter e sites. Se você quiser se aprofundar em um assunto, considere se juntar a uma lista de discussão ou de notícias.
• Se você realmente quiser ficar imerso em uma tecnologia, coloque a mão na massa – escreva algum código.
• Sempre tente trabalhar com pessoas mais experientes; ser o melhor pode paralizar seu aprendizado. Embora você possa aprender com qualquer pessoa, aprenderá muito mais com alguém mais inteligente ou mais experiente que você. Se não conseguir encontrar um mentor onde trabalha, considere seguir outros caminhos.
• Use mentores virtuais. Procure autores e desenvolvedores na Web que você goste de ler. Assine seus blogs.
• Conheça os frameworks e bibliotecas que você usa. Saber como algo funciona faz com que você saiba como usá-lo melhor. Se forem código aberto, melhor ainda. Use o depurador para percorrer o código para ver o que está acontecendo por baixo dos panos. Você vai começar a ver códigos escritos e revisados por pessoas realmente inteligentes.
• Sempre que você cometer um erro, corrigir um bug, ou tiver um problema, tente entender o que aconteceu. É provável que alguém já tenha passado pelo
mesmo problema e tenha postado na web. o Google é bastante útil nesse momento.
• Uma boa maneira de aprender algo é ensinar ou falar a respeito. Quando as pessoas lhe ouvem e lhe fazem perguntas, você fica mais motivado
a aprender. Tente ensinar algo a seus colegas de trabalho, em um grupo de usuários, ou em uma conferência local.
• Faça parte ou inicie um grupo de estudos ou um grupo de usuários para uma linguagem, disciplina ou tecnologia em que esteja interessado.
• Vá a conferências. E se não puder ir, muitas conferências disponibilizam suas palestras online gratuitamente.
• Vai fazer uma longa viagem? Ouça a um podcast.
• Você costuma executar alguma ferramenta de análise estática de código, ou verifica os warnings na sua IDE? Entenda o que eles estão relatando e por quê.
• Siga os conselhos do “The Pragmatic Programmer”* e aprenda uma nova linguagem a cada ano. Ou ao menos aprenda uma nova tecnologia ou ferramenta. Esses estudos podem lhe dar novas idéias, que você pode usar com suas tecnologias atuais.
• Nem tudo o que estudar tem de ser sobre tecnologia. Entenda o domínio em que está trabalhando, assim você poderá entender melhor os requisitos e
ajudar a resolver problemas de negócio. Aprender a ser mais produtivo, como trabalhar melhor, é outra boa dica.
• Volte para a escola. Faça um novo curso.
Seria bom ter a capacidade que tem o Neo, em Matrix, e simplesmente baixar as informações que precisamos para nossos cérebros. Mas não temos, por isso temos que assumir um compromisso mais longo de aprendizado. Você não precisa gastar cada hora acordado estudando. Um curto período, digamos uma vez por semana, já é melhor que nada. Há (e deve sempre haver) uma vida além do trabalho.
A tecnologia muda rapidamente. Não fique para trás.
Clint Shank
97 Things Every Programmer Should Know: Collective Wisdom from the Experts, Kevlin Henney, O'Reilly Media, Fevereiro de 2010, pág. 36.

segunda-feira, 21 de outubro de 2013

Nada substitui o lucro

Se você é um programador apaixonado pelo que faz, já deve ter sofrido bastante ao ver seus chefes, coordenadores, gerentes, ou patrões ignorando questões técnicas de suma importância, para você, como a manutenção de um código fonte de qualidade por exemplo, para viabilizar o cumprimento de um prazo ou algum requisito contratual. Isso é realmente frustrante e deve lhe fazer reclamar bastante pelos corredores e reconsiderar sempre a possibilidade de mudar de emprego, certo?

Não adianta. Onde quer que vamos estamos sempre sujeitos a isso. Você pode até mesmo encontrar uma empresa bacana de se trabalhar, onde os valores técnicos são tão considerados quanto os valores gerenciais, mas se de repente essa empresa entra em crise, rapidamente começaram as demissões, estagiários brotando do chão, agilidade sendo substituída por métodos tradicionais e a qualidade sendo deixada novamente em segundo plano.

Nada substitui o lucro, e isso é algo que você desenvolvedor, por mais bem intencionado que esteja, por mais profissional que seja, e por mais comprometido que se mantenha com a qualidade do código que escreve, não deve deixar de considerar. E não veja isso como algo ruim, ou errado. De fato nada substitui o lucro. Nenhuma empresa é constituída com o objetivo de criar o melhor software se isso não for apenas um meio de levá-la ao lucro. No fim, o que toda empresa busca é o lucro. 

Como então criar software de qualidade se o que interessa à empresa para a qual você trabalha é apenas lucrar? Se um software porcamente feito for mais lucrativo, é isso que a empresa irá lhe demandar, certo? Nem sempre. Cada organização tem seus valores, e muitas já reconhecem que produto de baixa qualidade uma hora ou outra se reverterá em prejuízo. Mas se esse não for o caso da empresa em que você trabalha, não entre numa guerra por interesses que deveriam ser daqueles que lutam contra. Faça sua parte, coloque qualidade no que você faz, na medida em que for possível, e não seja perfeccionista demais, seja mais pragmático. Aprenda também a aceitar que muitas vezes o nível de qualidade necessário será muito inferior ao melhor que você tem capacidade de entregar. Entenda os objetivos do projeto, compartilhe deles, e dentro desse limite, faça o seu melhor.


segunda-feira, 14 de outubro de 2013

5 segredos para um propósito compartilhado

Um dos pré-requisitos para um trabalho em equipe saudável e eficiente é sem dúvida ter um propósito compartilhado pela equipe. Abaixo listo 5 segredos elencados por Christopher Avery para facilitar esse objetivo.
1. Estabelecer um entendimento compartilhado:
Discuta cada tópico, a missão, os entregáveis, e o produto do trabalho de sua equipe, até que possam articular juntos uma descrição clara e comum de seu propósito.
2. Selecione sua equipe por sua motivação, não por suas qualificações.
Se trabalho em equipe é importante para você, olhe para as qualificações apenas após considerar diretrizes, energia, interesse, motivação e entusiasmo, por que é um desejo compartilhado, não taleto, que gera trabalho em equipe.
3. Aceite, de uma vez por todas, que colegas de equipe não precisam gostar uns dos outros.
Encorajar afinidade para uma tarefa compartilhada, não para um com o outro, é a maneira mais rápida e certa de criar forte coesão no grupo. Ao invés de usar exercícios e técnicas que promovam a amizade, faça todos adotarem um foco comum de modo que cada membro da equipe veja boas razões para trabalhar um com o outro.
4. Pare de tentar motivar.
Por que tentar motivar outras pessoas quanto isso é quase impossível? Ao invés disso, use a motivação que já existe nos membros da equipe perguntando a eles sobre suas necessidades e desejos.
5. Determine se seu time está "construído".
Um time "construído" compartilha direcionamento e energia. Para atingir esse status para seu time, coloque sua fundação bem cedo perguntando a você mesmo uma variedade de importantes questões. Qual é a tarefa da equipe? Qual o benefício para cada membro da equipe ao se comprometer com esse trabalho? Há acordos que permitam à equipe operar mais rapidamente e eficientemente? Os membros da equipe compartilham um objetivo comum que os inspire? Você sabe o que cada membro da equipe agrega ao time?

quarta-feira, 9 de outubro de 2013

Você não pode ganhar todas

Muitas foram as vezes em que me frustrei ao tentar convencer a outros, em especial quando eram superiores hierárquicos, a adotarem uma solução proposta por mim. Na maioria das vezes, diante de um problema, o que eu fazia era elaborar a melhor solução que eu fosse capaz, analisava cada detalhe, não deixava nada de fora, e por fim apresentava aos interessados, muitas vezes nem tão interessados assim, um solução única. Obviamente não era uma solução perfeita, mas já era uma solução bastante questionada e analisada.

O resultado disso, na maioria das vezes, era uma rejeição com base em argumentos mal fundamentados, mal pensados, que não consideravam todo o contexto, que dava importância a fatos irrelevantes e desconsiderava os fatos realmente importantes. Obviamente esse tipo de rejeição é bastante revoltante. No entanto, isso é bastante comum de se ver em situações como essa. Mas há justificativa.

Muitas vezes nós de fato não demos os pesos certos aos fatores considerados, ao menos não segundo a ótica dos demais interessados. Outras vezes não temos todo o domínio do contexto, não conhecemos todos os fatos que serão considerados pelos tomadores de decisão. E outras vezes o tomador de decisão simplesmente erra feio mesmo. O fato é que não podemos ganhar todas. Perderemos muitas. Por motivos legítimos ou por motivos idiotas. Mas essa é a realidade.

Diante disso, já há algum tempo mudei minha tática e ao invés de me focar em obter uma única melhor solução para os problemas que me dedico a resolver, passei a elaborar e propor várias. Na maioria das vezes nenhuma delas trará o melhor resultado de imediato, muitas vezes deixaram a desejar, mas todas elas resultarão em uma realidade melhor que simplesmente continuar convivendo com o problema.

E o que observei com essa mudança de comportamento foi que agora vejo boa parte das minhas propostas sendo colocadas em prática, ainda que muitas delas continuem sendo rejeitadas por uma razão ou outra. Diante de problemas que sei ser capaz de ajudar a resolver, vejo pequenos avanços sendo dados, pequenas ideias sendo implementadas e fazendo a diferença.

Se você é uma pessoa pró-ativa como eu e que não consegue ficar inerte diante de um problema passível de solução, não tente elaborar uma solução fantástica que mudará a realidade para sempre. Pense em pequenos avanços, proponha pequenas mudanças, e proponha muitas delas. Se você for mesmo bom no que faz, aquelas que forem aceitas já poderão tornar a realidade um pouco melhor e lhe darão credibilidade para que seja ouvido novamente no futuro.

sábado, 28 de setembro de 2013

O que é um programador profissional?

A característica mais importante de um programador profissional é responsabilidade pessoal. Programadores profissionais assumem responsabilidade por suas carreiras, suas estimativas, seus compromissos com o cronograma, seus erros, e sua criação. Um programador profissional não passa essa responsabilidade para os outros.

  • Se você é um profissional, então você é responsável por sua carreira. Você é responsável por ler e aprender. Você é responsável por estar atualizado com a industria e a tecnologia. Muitos programadores sentem que é responsabilidade de seus empregadores treiná-los. Desculpe, isso está simplesmente errado. Você acha que médicos se comportam assim? Você acha que advogados se comportam assim? Não, eles se treinam em seu próprio tempo, e com seu próprio dinheiro. Eles passam muitas de suas horas vagas lendo artigos e decisões. Eles se mantém atualizados. E assim devemos fazer. O relacionamento entre você e seu empregador é bem descrito no seu contrato de trabalho. Em resumo: seus empregadores se comprometem a lhe pagar, e você se compromete a fazer um bom trabalho.
  • Profissionais assumem responsabilidade pelo código que escrevem. Eles não liberam código a menos que saibam que funciona. Pense sobre isso por um minuto. Como você pode considerar-se um profissional se pretende liberar código sobre o qual não está seguro? Programadores profissionais esperam que o QA não encontre nada por que eles não liberam seu código até que o tenham testado por completo. Claro, QA sempre encontra algum problema, por que ninguém é perfeito. Mas como profissionais, nossa atitude deve ser não deixar nada para o QA encontrar.
  • Profissionais são jogadores de equipe. Eles assumem responsabilidade pela entrega de todo o time, não apenas pelo seu próprio trabalho. Eles ajudam um ao outro, ensinam um ao outro, aprendem um com o outro, e até mesmo substituem um ao outro quando necessário. Quando um colega de equipe está mal, os outros intervêm, sabendo que um dia serão eles que precisaram de ajuda.
  • Profissionais não toleram grandes listas de bugs. Uma lista de bugs enorme é desleixo. Sistemas com milhares de issues em sistemas de issue-tracking são tragédias do descaso. De fato, em muitos projetos, a simples necessidade de um sistema de issue-tracking já é um sintoma de descaso. Apenas sistemas muito grandes deveriam ter uma lista de bugs tão longa que alguma automação seja necessária para gerenciá-la.
  • Profissionais não fazem bagunça. Eles tem orgulho de sua criação. Eles mantém seu código limpo, bem estruturado, e fácil de ler. Eles seguem padrões acordados e boas práticas. Eles nunca, jamais se apressam. Imagine que você está tendo uma experiência fora do corpo assistindo um médico realizando uma cirurgia em seu coração aberto. Esse médico tem uma deadline (no sentido mais literal). Ele deve finalizar antes que a máquina de circulação artificial danifique demais as suas células vermelhas. Como você quer que ele se comporte? Quer que ele se comporte como um típico desenvolvedor de software, correndo e fazendo bagunça? Quer que ele diga, "Voltarei e corrigirei isso depois"? Ou quer que ele se atenha cuidadosamente a suas disciplinas, tomando seu tempo, confiante que sua abordagem é a melhor abordagem que ele pode razoavelmente tomar. Você quer uma bagunça, ou profissionalismo?
Profissionais são responsáveis. Eles assumem responsabilidade por suas carreiras. Eles assumem responsabilidade por fazerem seu código funcionar apropriadamente. Eles assumem responsabilidade pela qualidade de sua criação. Eles não abandonam seus princípios quando as deadlines os assombram. Na verdade, quando a pressão monta, profissionais se atém ainda mais forte às disciplinas que eles sabem serem corretas.

Robert C. Martin (Uncle Bob)

97 Things Every Programmer Should Know: Collective Wisdom from the Experts, Kevlin Henney, O'Reilly Media, Fevereiro de 2010, pág. 134.

quinta-feira, 25 de julho de 2013

Substituindo SVN por Git

Após alguns anos trabalhando com ferramentas de controle de versão centralizado, como StarTeam e Subversion (SVN), e já tendo feito algumas experiências com Mercurial e Git, usando BitBucket e GitHub como repositórios remotos, decidi iniciar um novo projeto usando Git, no entanto configurando meu próprio repositório remoto.

Numa empreitada como esta, três desafios normalmente precisarão ser superados:

  1. Configurar um repositório remoto e um repositório local e colocá-los para conversar educadamente. Essa tarefa é bem fácil e detalho mais adiante.
  2. Convencer os membros da equipe, acostumados com a comodidade do TortoiseSVN e com um processo de commit mais simples, que Git irá facilitar a vida deles, não o contrário. Isso também não será difícil, e há um modo suave de se fazer essa transição, que apresentarei a seguir.
  3. Convencer a empresa a aceitar os riscos de substituir o já conhecido SVN pelo Git, ainda que apenas num primeiro projeto. Isso será um pouco mais difícil, mas há algumas alternativas, caso isso não possa ser feito.

Para solucionar o primeiro problema, basta seguir este simples script:

  • Instale o Git, ou "GitHub for Windows", no servidor que será usado como repositório remoto.
  • No servidor onde o Git foi instalado, escolha uma pasta para hospedar o repositório remoto.
  • No Git Shell, navegue para a pasta escolhida e inicialize o repositório remoto com "git init --bare".
  • Instale o Git, ou "GitHub for Windows", em uma estação de trabalho.
  • Nessa estação de trabalho, escolha uma pasta para hospedar o repositório local.
  • No Git Shell, navegue para a pasta escolhida e inicialize o repositório local com "git init".
  • Monte dentro desse repositório a estrutura de pastas para o projeto.
  • Adicione a estrutura do projeto no git com "git add .".
  • Comite os arquivos recém adicionados no git, com "git commit -m 'Primeiro Commit'"
  • Configure o repositório remoto a ser usado pela estação de trabalho com "git config remote.origin.url endereço_do_repositorio_remoto".
  • Envie seu primeiro commit para o repositório remoto com "git push origin master"
  • Concluído. A partir agora você já poderá usar seu repositório local enviando os commits para o repositório remoto.
Para convencer a equipe a ao menos experimentar o Git, pode ser necessária muita conversa sobre as diferenças entre sistemas de controle de versão centralizados e distribuídos.

Apresentar a eles o "Git Game"  também pode ser útil.

No caso de equipes acostumadas a não usar ferramentas de linha de comando, esta será provavelmente a principal barreira. Para isso há duas ferramentas, em ambiente Windows, que podem ajudar. A primeira seria o TortoiseGit, semelhante ao provavelmente já conhecido TortoiseSVN, e a segunda o "GitHub for Windows". Quando trabalho com SVN, utilizo o TortoiseSVN, no entanto nas experiências que já fiz usando o GitHub usei o "GitHub for Windows", e esta será a ferramenta que usarei neste novo projeto.

Fica claro, pelo que disse acima, que o "GitHub for Windows" pode ser usado sem problema com repositórios remotos que não sejam repositórios do GitHub. Phil Haack, desenvolvedor da ferramenta, já falou sobre isso, no entanto utilizando um outro provedor de repositórios remotos, no caso o CodePlex. No nosso caso, precisamos usar o "GitHub for Windows" com um repositório remoto disponível na nossa intranet.

A configuração desse repositório remoto já foi feita acima, e sua utilização com o "GitHub for Windows", não poderia ser mais simples. Basta arrastar o repositório local, já configurado para enviar os commits ao nosso repositório remoto, para dentro da janela do "GitHub for Windows" e clicar no botão "Publish". A partir dai o botão "Sync" ficará disponível e poderá ser usado para sincronizar o repositório local com o repositório remoto. O uso dessa ferramenta pode tornar a aceitação do Git pela equipe bem mais simples.

Já para o terceiro desafio, o processo de convencer a empresa a experimentar o Git pode ser o mesmo usado com a equipe, ressaltando principalmente os ganhos de produtividade devidos a melhor performance e a maior segurança caso um desastre aconteça com o repositório remoto.

No entanto, caso a empresa se mantenha relutante, nada impede o uso misto de Git e SVN. Para isso pode ser usada a ferramenta "git svn", ou simplesmente usar um repositório local Git, e ter todas as vantagens que esse repositório local oferece, como a possibilidade de fazer vários commits, reverter alguns deles e "reordená-lo" antes de enviar ao repositório remoto, e um repositório remoto SVN, sendo sincronizado com o repositório local do modo tradicional. Ou seja, você trabalha localmente com Git até que seu código esteja em condições de ser compartilhado com a equipe, e nesse momento faz esse compartilhamento através de SVN, normalmente. Obviamente que com essa última abordagem, assim como com o uso de "git svn", muitas das vantagens do Git serão perdidas, mas ao menos você poderá fazer uso de parte delas.