Escrever errado… #atequando?

Nos comunicamos através de códigos e esses códigos são as línguas, que tornam possível interagirmos com outras pessoas. Primeiro,  aprendemos a falar e aos poucos vão nos ensinando algumas regras. E existem regras básicas, por exemplo o pronome oblíquo tônico “mim”, que  não deve ser usado na conjugação de um verbo, mim não leva, mim não faz, … Mas muitos cometem esse deslize. Depois aprendemos a escrever e várias outras regras que formam a gramática da língua. Com isso temos a possibilidade de espalhar nosso pensamento estando presente ou não. A escrita possibilita e-mails, slides em uma apresentação, comunicar procedimentos, ações ou proibições em placas de trânsito; artigos em jornais, revistas, livros, blogs, … Uma infinidade de possibilidades, até mesmo nos tornarmos imortais.

Uma frase muito comum dita por vários desenvolvedores de software em listas de discussão ou no cafezinho na empresa é: “Não preciso saber escrever,  o meu negócio é escrever código”. Isso é uma verdade? Nós desenvolvedores não precisamos saber nos expressar na língua portuguesa escrita? Um desenvolvedor escreve e-mail? Escreve um documento no Word? Ou abre uma thread em alguma lista de discussão? É lógico que sim! Um desenvolvedor de software precisa muitas vezes saber se comunicar por escrito. E precisa fazer isso de maneira extremamente correta para se fazer entender e para isso deve fazer uso das regras gramaticais, ortográficas [tem mais alguma?]. Ou não se vai  entender mesmo! Escrever errado só mostra o seguinte: Você já era incompetente no primário ou ficou preguiçosamente vagabundo depois de adulto.

Quem acha que não precisa escrever direito muitas vezes também não gosta de ler. Pergunta para alguém que disse que não precisa escrever direito qual o último livro que ela já leu. Pergunte qual o livro que ela está lendo ou qual livro na área de desenvolvimento ela leu ultimamente e que a ajudou ou que foi interessante. Você vai ficar sem resposta provavelmente. Ler é essencial e, para escrever bem é preciso ler também. A leitura no mínimo serve como a manutenção do nosso aprendizado da língua.

Se você acha que não precisa escrever português direito… como é o seu código?

A maior parte do tempo um desenvolvedor vai escrever, ou pelo menos deveria! Ele não vai escrever a maior parte do tempo e-mails, artigos, posts ou threads de discussão, ele vai escrever código em um língua que o compilador vá entender e depois transformar em uma língua que a máquina vai entender. As linguagens de programação de sua própria sintaxe, regras. Existem palavras reservadas, regras de sintaxe que, se não obedecidas, seu código simplesmente não vai funcionar. As vezes nem irá compilar! Para a sorte de muitos, erros básicos (o “dá pra mim fazer”), da linguagem de programação são pegos pelo compilador, algumas linguagens funcionam diferente.

Indo além, como é a legibilidade do seu código? Não basta só saber usar as palavras reservadas em uma ordem que funcione, é preciso também escrever bem o seu código. Chovendo no molhado,  é preciso descrever bem o que você quer dizer com aquele código, o @vquaiato já blogou sobre o assuntou quando estava comentando o Clean Code (aliás: você já leu o livro? 😀 ).

Quando estiver escrevendo um código assim você poderá aplicar Command and Query Separation! O Uncle Bob escreveu apenas uma página no livro, mas acho um assunto bem interessante e tenho procurado colocar isso no meu código. A ideia aplicada em funções é que elas façam alguma coisa ou respondam alguma coisa, nunca as duas ações juntas. Exemplo:

[code lang=”csharp”]
namespace CQS
{
class Program
{
static void Main(string[] args)
{
CalculoAumentoDeSalario calculo = new CalculoAumentoDeSalario();

decimal SalarioComAumento = calculo.CalculaAumentoERetornaSalario(10);
Console.WriteLine("Salário com aumento: {0}", SalarioComAumento);
Console.ReadKey();
}
}
public class CalculoAumentoDeSalario
{
private decimal Salario = 1000;
//…
public decimal CalculaAumentoERetornaSalario(decimal percentualAumento)
{
//…
Salario = Salario + (Salario * percentualAumento / 100);
//…
return Salario;
}
}
}
[/code]

Repare no código acima que nem tudo o que o método CalculaAumentoERetornaValor vai fazer está explicito no seu nome, para quem lê só a chamada da função vai entender que irá ser calculado o aumento e retornado e não que já irá alterar o valor do salário. Se essa classe que estiver sendo persistida uma conferência de valor, já que para aumentar o cálculo real compreende vários impostos e realmente é preciso uma conferência; o sistema seria comprometido!

Fazendo um refactoring, melhorando nomes, aplicando CQS:]

[code lang=”csharp”]
namespace CQS
{
class Program
{
static void Main(string[] args)
{
Salario salarioFuncionario = new Salario();
salarioFuncionario.AplicaAumento(10);
Console.WriteLine("Salário com aumento: {0}", salarioFuncionario.Valor);
Console.ReadKey();
}
}
public class Salario
{
public decimal Valor { get; set; }
public Salario()
{
Valor = 1000;
}
//…
public void AplicaAumento(decimal percentualAumento)
{
//…
Valor = Valor + (Valor * percentualAumento / 100);
//…
}
}
}
[/code]

O código ficou mais legível, os nomes refletem melhor o que as funções fazem. Esse é um código de exemplo, alguns nomes ficariam ainda melhores em um código funcional. A função agora realmente só tem uma única função. Faça o teste no seu código!

Obs.: Encontrando algum erro de português nesse post se atenha ao conhecimento, ou seja, faça o que eu digo e não faça o que eu faço. #Bazinga

UPDATE, links úteis:

CommandQuerySeparation, por Martin Fowler

CQRS, por Martin Fowler

CQRS, por Udi Dahan

Brownfield, Greenfield, Legacy, … O que é tudo isso?

Motivado pela minha participação no Void podcast, episódio #017 – Strawberry Brownfields Forever, (valeu pelo convite Elemar Jr. (@elemarjr), Leandro Daniel (@leandronet) e Vinícius Quaiato (@vquaiato)) resolvi começar a publicar uma série que eu estava preparando desde o ano passado, como uma continuação da palestra sobre o tema que fiz em duas cidades, São Paulo e Florianópolis, no TDC 2011, post sobre o evento, e aproveitando já foi liberada a data do evento esse ano, entre no site: The Developers Conference.

Brownfield

Apesar de trabalhar com Brownfield, não sabia que existia um nome para este “momento” ou situação no desenvolvimento. Me deparei com o termo ao encontrar o livro Brownfield Application Development in .NET, de Kyle Baley and Donald Belcham, publicado na Manning Publications Co.,o qual existe versão PDF, ePub e MOBI, veja aqui. O engraçado é que o título do livro dá a entender que o assunto será construir uma aplicação Brownfield! o_O Não poderia estar mais errado!

O termo é uma analogia a um terreno que está contaminado por lixo ou entulho, mas tem potencial, se for feita uma limpeza. No desenvolvimento de software o termo é a classificação de uma aplicação que sofreu a ação do tempo em suas linhas de código, ou seja,  uma aplicação que foi recebendo atualizações, modificações, até mesmo de objetivo; sem uma preocupação com a qualidade e como essas ações interferem  no código, deixando o processo de atualização ruim.

Mas não é só uma aplicação já em produção que se torna Brownfield. No início de um novo desenvolvimento, chamamos a aplicação de Greenfield, um campo novo no qual começamos a criar. Se não tomarmos cuidado,  essa aplicação já vai entrar em produção como Brownfield!

Do Green ao Brown

Quando não planejamos corretamente, não analisamos totalmente ou não temos toda a informação é que surgem as péssimas técnicas, metodologias, processos, que não precisam ser ensinadas, elas simplesmente acontecem na nossa cabeça. É mais difícil fazer algo bem feito do que algo mal feito. É simples, rápido, fácil, parecem ser características boas, mas são somente em um primeiro momento, ou a curto prazo! Porém,  quando se desenvolve um software ele não é uma solução de curto prazo ou uma ferramenta temporária, mas pelo contrário, vai durar e bastante. Todo mundo já ouviu alguém pedir uma solução momentânea, que ganha atualizações por que outra área achou interessante usar também, e que no fim vai ficando e ficando, e dali a algum tempo é core dos negócios da empresa. Uma simples parada para manutenção desse serviço poderá causar perda financeira para o negócio. Se um chef de cozinha, que está cozinhando uma refeição, que será consumida em seguida e em uma ou duas horas, mantém seu ambiente de trabalho limpo e organizado. Por quê é diferente quando se está codificando algo que vai existir por meses, anos, talvez décadas?

Exceções existem! Existem aplicações que tem um tempo de vida tão curto que invalida a necessidade de técnica, práticas, metodologias; e não estou falando de simples scripts para automatização de tarefas.  Na Forward Internet Group, uma empresa londrina, as aplicações nascem e morrem muito rapidamente! Como o foco são campanhas publicitárias que entram e saem rapidamente do ar,  para eles não existe a necessidade de fazer testes! Até mesmo por que a aplicação é tão pequena que os testes poderiam ter mais linhas de código do que a própria aplicação. Veja mais nessa apresentação da QCon 2011, em Londres.
Por isso não gosto tanto da definição do Michael Feathers de que código legado é código sem teste, pois invalida outros cenários ou situações.

A falta de planejamento constante, validando as funcionalidades a serem implementadas,  se realmente se encaixam no domínio do problema que o software se propõe a resolver; de refactoring; fazendo a limpeza do código que está sendo produzido; de controle da dívida técnica e até mesmo da organização da equipe de desenvolvimento, do turnover, levam uma aplicação do Greenfield ao Brownfield, às vezes de maneira assustadoramente rápida.

Ninguém gosta de trabalhar nesse tipo de código. Alterações tendem a gerar problemas inesperados, que fazem a equipe estender o horário de trabalho, a dificuldade de evolução faz você trabalhar nos fins de semana,  você não consegue mudar um framework de maneira simples,  não é preciso dizer que o custo aumenta exponencialmente com o passar do tempo. Uma verdadeira bola de neve, ou mais tecnicamente, um código macarrônico sem fim.

Lá e de volta outra vez…

Não é uma solução viável simplesmente reescrever o código, já que se estaria solucionando o sintoma somente e não o problema. Sair de um Brownfield não é fácil, é bem trabalhoso, mas trabalhoso por trabalhoso é melhor você se empenhar para resolver o problema do que continuar apenas queimando tempo em problemas recorrentes causados pelo desleixo com o código.

No episódio do podcast chegamos a conclusão de que alguns passos são inevitáveis:

  1. Convencer sua equipe: de que existem outras soluções, outras maneiras de trabalho; de que é possível entregar algo de qualidade com mais facilidade do que entregar com baixa qualidade
  2. Conseguir apoio para mudar: ou você resolve na calada da noite ou consegue que algumas horas gastas nas melhorias
  3. Refactoring, técnicas, metodologias: são necessárias ou você terá muito mais trabalho e não vai compensar e vai desistir
  4. Métricas: é preciso mostrar onde foi a melhoria, o que ela trouxe de benefícios

Próximos passos

Leia o livro indicado no começo do post e acompanhe o blog, vou publicar mais textos sobre o tema. Comentários são bem vindos. Até.

Com canudo por quê?

Eu tomo café da manhã na padaria: um suco de laranja e um croissant. Como vou sempre na mesma,  o atendente já me conhece, mas quando ele começou lá foi a mesma coisa do anterior, ele me servia o croissant, servia o suco e ia pegar um canudo, que eu sempre recusava (questões ambientais)… Se você pede um suco sempre colocam um canudo, mas se você pede um refrigerante, um chocolate quente, uma água com gás, uma cerveja… não colocam! Por quê? O copo é o mesmo. Acho que quando inventaram o canudo era para você conseguir beber um líquido de um lugar do tipo uma garrafa, ou até mesmo acho que era para crianças. Não tem  sentido servir um suco com canudo e um refrigerante sem!
No desenvolvimento de software é a mesma coisa. Não usamos canudo, mas já perceberam como fazemos coisa que não sabemos por quê? Alguém fez a primeira vez, talvez para resolver um problema específico, e outro copiou, depois outro… E de repente está todo mundo fazendo, e ninguém sabe por quê.
Por quê se usa Dataset’s? Além do fato de vários livros de .Net básicos ensinarem e o pessoal parar de estudar no básico ou intermediário, se você perguntar para algum desenvolvedor o motivo que o levou a usar Dataset ele não vai saber explicar. Teve alguma vantagem? Ele não vai saber. É mais rápido? Ele não vai saber.
Por quê usamos Try…Catch? Muitos desenvolvedores não vão saber explicar! Aliás, muitos não sabem nem mesmo usar! Ou alguém nunca viu um método FazTudo com um Try…Catch abrangendo um código gigantesco?
Por quê ainda usamos ADO.Net puro quando temos outras maneiras melhores de acessar um banco de dados? Por quê programamos estruturado em uma linguagem orientada a objetos?
Meu pai fala uma frase: “O ser humano é um animal acostumado a hábitos”.
Nós simplesmente acostumamos a fazer alguma coisa e isso vira um processo, sempre se repetindo, sem espaço para inovação, criatividade, pensar fora da caixa. E a sociedade, a vida cotidiana, força-nos mais ainda a manter esse hábito de repetição (olha a recurividade aí, hábitos já são repetitivos).
Os estudantes não são ensinados a pensar e sim a repetir, a decorar, desde os primeiros anos. Não são forçados a questionar, a verificar, a pesquisar, a tentar entender e quem sabe no futuro entender esse conhecimento sozinho. Anos atrás por conta da pobreza dos editores das linguagens de programação e também por causa da fraca tipagem era uma questão de bom senso usar um prefixo com o tipo da variável.

[code lang=”c”]<br />
float fValorTotal;<br />
int iQuantidade;<br />
[/code]

Mas era algo totalmente justificável, pois você não tinha algo como o Intellisense do VS.Net, você podia atribuir um valor decimal para uma variável declarada como inteira, e por aí vai. Mas e hoje, por quê ainda se usa esse prefixo? E por quê ele é ensinado em muitos lugares? Não tem o menor sentido. E os alunos habituados a anos a decorar sem questionar não conseguem perceber que sem o prefixo o código compila da mesma maneira.
Por quê ao ensinar o paradigma de orientação a objetos não deixamos de codar estruturado? Temos ainda o paradigma funcional, dinâmico, … Mas essa distinção não é clara para recém formados ou participantes de cursos de programação. Por que até hoje se ensina OO como se fosse uma evolução do estruturado, o que nunca foi uma verdade.
Hoje os bancos usam programação estruturada, indústrias com seus softwares MRP também, esse tipo de linguagem não vai sumir, ela tem o seu uso, e o OO não é o futuro dela.
Manter a mente aberta para o aprendizado é algo extremamente difícil, questionar processos, discutir teorias, é complicado, pois somos avessos a mudanças. Albert Einstein, disse: “A mente que se abre a uma nova idéia jamais voltará ao seu tamanho original”. E é assim que deveríamos agir em todos os momentos da nossa vida, e precisamos de pessoas que queiram experimentar, criar, aprender e evoluir principalmente na área de software. Quem sabe assim termos mais qualidade, seremos mais econômicos, mais rápidos e assertivos. Só depende de quem faz.