Posts Marcados Ágil

Profissão Codificador

Acho que a carreira de muitos de nós, programadores, começa de maneira similar: usualmente em algum momento da adolescência temos contato com computadores, ficamos fascinados por eles (na minha época foi um Gradiente Hotbit MSX, com programação BASIC) e a partir daí começamos a programar. E se você está lendo este blog, é grande chance de que nunca mais você tenha parado!

Mas me pergunto como será o nosso futuro nesta carreira. Tirando os que mudam de área (viram gestores, analistas de “negócio”, instrutores ou simplesmente vão fazer outra coisa) ou os que passaram em concurso público (este é um assunto que eu nem vou entrar!), eu fico imaginando como seria o futuro dos que continuam a programar. Alguns se tornam consultores independentes famosos, o que irá garantir uma aposentadoria tranquila escrevendo livros, artigos e ministrando palestras. Mas acho que  atualmente a maioria dos bons codificadores trabalha no esquema de pessoa jurídica, para um ou mais clientes e vive da capacidade de horas que consegue fazer. E até quando? Em algum momento isto vai ficar cansativo, ou ele vai se desatualizar e vai sair do mercado (interessante que, salvo raras exceções esta ainda é uma área quase 100% masculina… mas isto é assunto pra outro post!). E qual será o destino destes codificadores?

Apesar de se trabalhar no esquema de pessoa jurídica implicar que se tenha um negócio, infelizmente esta é uma profissão com muito pouca “escala”, já que o limite são as horas que cada um consegue fazer no mês. Mesmo para os que têm uma veia empresarial e que contratam um ou mais auxiliares, esbarra-se no limite de gestão de equipe (que pra mim varia de 4 a 7 pessoas). A partir daí, a qualidade cai ou se começa a ter dificuldade de garantir entregas ou prazo. E as tentativas de crescimento com equipes maiores são extremamente complicadas – falo por experiência! E não é fácil ter um negócio dependente da venda de projetos ao invés de horas; da maneira que eles como são vendidos hoje, em regime de preço fechado, eles tem um risco altíssimo, que quase sempre é negligenciado para se garantir o melhor custo, resultando em mais prejuízos do que sucessos.

Assim me pego muitas vezes pensando neste assunto. Nossa profissão é jovem, ou seja, não tem muita gente no final de carreira ainda. Mas estamos prestes a chegar lá. E acho que se não começarmos a pensar e atuar nisto, pode ser que para a maior parte de nós, este fim de carreira não seja uma experiência muito tranqüila.

Outro ponto interessante é que os que permanecem codificando são justamente os melhores desenvolvedores. E lembrando da regra de 10:1 de produtividade (como o Steve McConnell sumariza bem aqui), isto significa que as pessoas que tem mais probabilidade de ter problemas no final da carreira são justamente as que são as grandes responsáveis por construir o que está sendo feito hoje, como líderes de times, arquitetos ou simplesmente “virando” noites para fazer aquele projeto atrasado e over budget ser entregue. De uma certa maneira, este grupo é a espinha dorsal dos que hoje fazem acontecer e que são usados pelos que não são tanto (para quem gosta de reflexões mais aprofundadas, recomendo o livro “Atlas Shrugged” da Ayn Rand. Escrito na década de 50, fala de uma sociedade onde poucas pessoas com excelência técnica e artística sustentam todos os demais até que elas se cansam e entram em “greve”… Muito interessante).

De certa maneira, a disseminação cada vez maior de metodologias ágeis melhora um pouco o cenário das pequenas empresas. A troca do modelo de venda em preço fechado por uma baseada em venda de equipes para iterações curtas beneficia todos, permitindo que os riscos sejam melhor gerenciados e expondo-os muito mais cedo no processo. Exemplos como a ThoughtWorks, que se especializou neste tipo de venda com sucesso mundial acabam incentivando a mudança de cultura que está em curso atualmente. Claro que vai demorar pra isto subir até que licitações públicas sejam feitas de forma diferente, por exemplo, mas acho que isto vai acabar acontecendo.

Mas isto não é a resposta para a grande maioria, que não tem vocação (ou interesse) em se transformar em empresários. E apesar de pensar bastante nisto, não vejo saída fácil e fico preocupado com o futuro destes desenvolvedores. Mas não deixo de conjeturar como seria se todos estes melhores codificadores se juntassem em algum tipo de empresa comum, onde a excelência técnica fosse aplicada na construção de produtos que resultassem em ganhos diretos. Interessante, não? Se alguém tiver pensamentos a respeito deste assunto, entre em contato!

, ,

5 Comentários

Desenvolvimento Ágil e Processos

Esta semana tive a oportunidade de conversar com vários clientes sobre o desenvolvimento ágil e a quantidade de controles e processos que devemos utilizar para suportá-lo. No meu caso, a virada de 180 graus de um desenvolvimento waterfall clássico (com especificação, aprovação e execução) para um desenvolvimento ágil teve como conseqüência inicial a abolição completa de controles e processos – até porque os controles e processos waterfall não se aplicam a um desenvolvimento ágil.

Porém, esta abolição completa está começando a gerar efeito colateral negativo, em dois aspectos: rastreabilidade de decisões e controle de faturamento. A deficiência nestes dois aspectos me foi apontada por clientes e vem sido também sentida internamente pela equipe de desenvolvimento.

A questão da rastreabilidade significa entender, às vezes muito tempo depois da implantação, porque uma determinada funcionalidade foi implementada de uma certa maneira ou porque determinada decisão de negócio (ou de arquitetura) foi feita em detrimento de outras. E, em um desenvolvimento ágil, isto comumente se perde já que os itens de backlog vão sendo implantados e código produzido, ainda que bem comentado, não é suficiente para se manter a visão destas características. Embora as práticas ágeis não sejam contra a documentação (muito ao contrário), fica a questão do quanto e como se documentar. Uma documentação que não seja realmente útil significa gastar horas que poderiam estar melhorando o ROI gerando novas funcionalidades.

A questão do faturamento do trabalho produzido por uma equipe ágil também é um ponto problemático.Mesmo assumindo que o cliente já tenha comprado a idéia de usar uma metodologia ágil, ainda assim ele vai querer uma contabilização do que foi gasto e aonde. E embora o product manager e o cliente específico da funcionalidade tenham uma comunicação extensiva, muitas  vezes existem outras pessoas para as quais é importante prestar conta das atividades realizadas. Ainda que a produtividade seja alta, algumas vezes é difícil se ter uma visão do trabalho gerado em cada interação, especialmente em longos períodos de tempo.

Desta forma, nestes dois aspectos, é necessário se definir artefatos e processos mínimos que sejam capazes de gerar e armazenar estas informações. No nosso caso, o que temos feito é tentar automatizar estes processos através de sistema interno específico, para minimizar o tempo despendido na geração destes artefatos e para padronizar as informações produzidas. Assim, para a gestão do backlog, controle das atividades realizadas em cada iteração e armazenamento de notas referentes às tarefas realizadas, estamos desenvolvendo um produto web específico que denominamos Iterator. Nele, teremos a gestão do backlog, a definição das iterações com as específicas tarefas, um amplo suporte a notas, descrições e arquivos anexados a cada tarefa e uma visibilidade por perfil. Ele possui também um módulo windows que é utilizado pelos desenvolvedores para apontar, de maneira simples, rápida e minimamente intrusiva, as atividades em que atuou, permitindo a visibilidade pelos membros da equipe e stakeholders do projeto.

Alguns podem achar que desenvolver um sistema internamente para isto é um overkill, já que existem alguns produtos voltados à gestão e controle do desenvolvimento ágil. Porém, os melhores que analisamos ou são caros (outro conceito relativo, mas caros no nosso cenário) ou são voltados exclusivamente para a gestão de backlog (sem o lado de faturamento) ou simplesmente são muito complexos para se adotar, gerando custo excessivo de treinamento e adaptação. Desta forma, acredito que o custo de desenvolvimento do Iterator (que com o framework, não é tão alto assim), acaba sendo compensado por estes fatores. Finalmente, existe o objetivo de transformá-lo em um produto, o que traz outras compensações.

Se alguém possuir necessidades similares ou que use um produto que não atenda completamente e quiser influenciar no desenvolvimento, basta entrar em contato. Conforme formos evoluindo e quando tivermos algo disponível publicamente, eu notifico a todos por aqui. Até a próxima.

, , , , , , , ,

Deixe um comentário

Produtividade – Princípios

Continuando a série sobre produtividade, e antes de entrar em detalhes da nossa plataforma atual, vou relacionar alguns princípios que utilizo quando o assunto é produtividade.

  1. Uso de tecnologia de ponta – como citado no post anterior, eu acredito que a incorporação de uma nova tecnologia ou framework só deve ser feita quando há um ganho claro mensurável. Nossa indústria muda muito rapidamente e muitas frentes às vezes aclamadas como excelentes práticas podem cair em desuso daqui a alguns meses. Isto posto, é fundamental estar atualizado, pois a todo tempo surgem soluções ou práticas que definitivamente podem gerar ganhos de produtividade. Eu me considero um dos últimos dos “early-adopters”, ou seja, nossa plataforma usualmente tem quase tudo que é de ponta, porém normalmente não sou um dos primeiros a adotar uma determinada novidade.
  2. Dogmatismos e guerras religiosas – Na nossa indústria é muito comum encontrar pessoas que defendem práticas ou teorias simplesmente por elas terem sido definidas, não importando que finalidade ou benefício possa advir do uso delas. Minha visão sobre isto não poderia ser mais pragmática, acredito que temos que conhecer muito bem a teoria e os conceitos envolvidos, porém o uso é condicionado ao ganho que possa ser obtido. Mesmo que isto signifique “deturpar” uma teoria ou usar somente uma parte dela. Nosso negócio não é o purismo e sim a produtividade, portanto, pra mim, não há espaço para dogmatismos. Tenho vários exemplos sobre este tema. Um muito comum é sobre “modelos anêmicos”, que tentam fazer um purismo OO quando, na minha experiência, isto causa mais problemas do que ajuda (mais sobre isto no post da camada de domínio). Não tenho nenhum problema em ter uma visão procedural de serviços, se desta forma estamos sendo mais produtivos. Outra é sobre uso de “patterns” conhecidos. Muitas pessoas ficam olhando um problema e tentando identificar e classificar aquilo em um pattern quando algumas poucas linhas de código já poderiam ter resolvido o problema há muito tempo. Quanto mais patterns conhecermos melhor, mas se usar não é intuitivo, algo provavelmente não está certo.
  3. Complexidade – Desenvolver sistemas significa fazer tarefas complexas. Mas para mim, a complexidade deve estar sempre que possível escondida das tarefas do dia a dia. Por exemplo, um framework de domínio vai ter áreas muito complicadas para se projetar e construir. No entanto, usar um framework de domínio deve ser algo simples. A todo o tempo eu avalio o esforço para se esconder as complexidades de tarefas comuns e quando há um potencial, isto é feito. Claro que a tarefa tem que ser comum o suficiente para compensar o esforço de encapsulamento; não faz sentido fazer um framework para uma tela que será desenvolvida uma única vez. CRUDs são usualmente candidatos a usar frameworks, pois todos os sistemas possuem várias telas deste tipo. Um corolário disto é que se for possível automatizar algo com o uso de DSLs, eu vou considerar esta opção de maneira muito favorável. DSLs tornam as tarefas do dia a dia mais simples, então pra mim isto significa produtividade direta. Infelizmente fazer uma DSL ainda é algo muito complexo, e utilizar uma pronta que não tenha nenhuma área de conflito é raro – se ela não se encaixar bem, não vai ser produtivo usar. Um exemplo muito bem sucedido na nossa equipe é o ActiveWriter, que é uma DSL para se gerar entidades de domínio. Atualmente nossa plataforma de domínio está tão boa que nossos desenvolvedores quase que esquecem que ela está lá, trabalhando com uma interface gráfica para desenhar entidades e gerando a maior parte do código com geradores automáticos. Outros exemplos nesta linha são o uso de interfaces fluentes, operadores customizados e assim por diante.
  4. Manutenabilidade – Este é um conceito sujeito a muitas guerras religiosas. Para muitos desenvolvedores, a busca da uma manutenabilidade máxima é o objetivo final, mesmo que isto não seja necessário. Na minha visão, a manutenabilidade de um sistema moderno está ligada a duas áreas: facilidade de alterar interfaces e facilidade de entender e identificar as regras de negócio. As demais áreas complexas (frameworks, camadas de domínio etc.) serão complexas, não importa quão bem feitas sejam. Então não adianta tentar deixá-las super simples de dar manutenção; se a equipe que as projetou não estiver disponível, vai ser difícil alterar. Claro que boas práticas de programação devem ser usadas nestas áreas, mas daí a tentar fazer algo universalmente simples pode ser um esforço inviável. No meu caso, eu me preocupo com telas e regras de negócio. Em termos de regras, temos tido bastante sucesso, hoje temos sistemas legados de quase 10 anos que ainda são simples de ter regras de negócio alteradas. Telas são um pouco mais complexas, pois a tecnologia mudou muito nos últimos anos, mas mesmo assim temos tido um razoável sucesso. Mais sobre isto no post referente a interfaces.
  5. Linguagens Declarativas – Outro tema polêmico, linguagens declarativas são linguagens que se propões a dizer o que deve ser feito ao invés de como deve ser feito. Exemplos são linguagens como SQL ou XSLT e qualquer outra DSL. Na minha visão, este é um dos maiores fatores de produtividade, pra mim linguagens declarativas SEMPRE são ordens de grandeza mais produtivas do que linguagens imperativas (C# etc.). Assim, no nosso caso, muitas extrações são feitas em SQL direto. Ultimamente HQL também tem sido uma excelente opção. (Obs.: não acho que regras de negócio devam estar em stored procedures, já que regras de negócio são procedurais e portanto, imperativas por natureza). E no nosso caso, o uso de XSLT é prevalente nas interfaces. Apesar de ter uma curva de aprendizado significativa, a minha opinião é que o esforço para aprender XSLT é sempre é retornado muitas vezes em produtividade – mais sobre isto no post sobre interfaces.
  6. Perfil da Equipe – Por último, um tópico que foi abordado no post anterior. Minha opinião é de que ter pessoas inexperientes vai afetar negativamente a produtividade, em qualquer cenário. Como visto nos itens acima, trabalhamos com todas as tecnologias de ponta, o que significa uma grande formação básica necessária. Na nossa equipe é muito raro um novo membro, por mais experiente que seja, não ter um tempo de adaptação de um ou dois meses. Para desenvolvedores inexperientes, este tempo seria muito maior, afetando de maneira drástica a produtividade geral da equipe. Este é um grande problema pois profissionais bons são raros, e uma troca de pessoal freqüente também afeta de maneira significativa a produtividade. Não vejo solução para isto, o que faço atualmente é ter pessoas chaves liderando as equipes que possam absorver eventuais necessidades por troca de pessoal, mas esta troca inevitavelmente vai diminuir a produtividade.

O próximo post é sobre a camada de dados de de domínio. Até breve.

, , , , , , , , ,

Deixe um comentário

O fim do arquiteto?

Nas últimas semanas tenho participado de várias discussões internas e em listas de discussão sobre composição de times de desenvolvimento. Este é um assunto especialmente interessante, pois a qualidade ou o custo do software que construímos é ultimamente o resultado da qualidade e do custo do time que o construiu.

A característica de rapidez da evolução da plataforma tecnológica de desenvolvimento faz com que se manter atualizado exija uma super especialização. Isto é muito difícil de ser feito e as pessoas com mais experiência e que conseguem se manter atualizadas acabam sendo conhecidas como “arquitetos” (categoria na qual eu me incluo). Elas dominam as múltiplas áreas de conhecimento de desenvolvimento e conseguem definir e ensinar como aplicar padrões e tecnologias de maneira adequada. No entanto, na minha visão, um dos maiores riscos deste grupo é que adotemos a busca da atualização tecnológica como o nosso principal e único objetivo e esqueçamos que na verdade o nosso objetivo é fazer software bom a um custo viável. Afinal, usualmente, o cliente não está interessado se o sistema dele é .NET, Java, usa DDD ou não, é feito via TDD ou não; o que ele quer é algo que ele perceba valor (ou seja, bom!) e que ele pague um custo que ele ache justo pra construir e manter o sistema.

Acho que no fundo, todos nós sabemos disto, já que provavelmente iniciamos nossa carreira fazendo algum sistema para alguém. Ocorre que quando as empresas vão crescendo, surge uma dificuldade de escala, já que temos que fazer um volume cada vez maior de horas de desenvolvimento. E, ao contratar mais pessoas, começam a existir os problemas usuais do desenvolvimento em equipe: aumento de custo e queda de qualidade. Várias alternativas têm sido propostas para lidar com isto, ligadas à própria origem da “Engenharia de Software” como disciplina, há décadas atrás. É muito interessante reler o livro “The Mythical Man-Month”, do Brooks. Os problemas que ele descreve na década de 60 sobre desenvolvimento baseado em Mainframe (!!) são praticamente os mesmos de hoje!

A abordagem mais em voga atualmente para lidar com o problema de escala é montar uma equipe hierárquica, normalmente sob coordenação de um gerente de projeto (nas maiores empresas, um PMP) e composta por pelo menos um arquiteto e um conjunto de desenvolvedores com mais e menos experiência (seniores e juniores). E usar um processo definido para garantir que os mínimos padrões de qualidade sejam atingidos e o custo controlado. Neste modelo, tenta-se diminuir o custo usando-se mais juniores e tentando evoluí-los com treinamento durante o desenvolvimento. Eu mesmo fui adepto deste modelo por muito tempo, mas confesso que, após muitos anos de tentativas, estou muito desapontado com os resultados. A cada vez os custos de produção aumentam, a qualidade continua ligada a somente a quem está construindo (e não ao processo) e manter um grau de satisfação na equipe é complicado. A tal ponto de que passei a não mais acreditar neste modelo e partir para a adoção de uma metodologia ágil.

Em desenvolvimento ágil as equipes são sempre pequenas e não há uma hierarquia rígida (há um líder técnico somente). O ciclo de entregas é curto e a preocupação com valor sendo entregue é o mais importante. Embora isto resolva vários problemas do desenvolvimento em equipe, ele tem um problema crítico de escala também, já que para grandes projetos seriam necessárias várias equipes e a orquestração disto não é trivial.

Neste cenário, estamos tentando ver como compor estas equipes ágeis. Tivemos várias experiências mal sucedidas com desenvolvedores menos experientes. O desenvolvimento ágil pressupõe muita autonomia e é difícil garantir qualidade e custo com juniores, já que o processo é bem leve e não há a preocupação com o treinamento em si. Alguns propõem o pair-programming como solução, porém algumas tentativas que fizemos nesta linha não foram também bem sucedidas. Isto tem nos feito buscar equipes somente com desenvolvedores super experientes. Ainda que sejam mais caros, os resultados têm sido melhores com um custo geral mais baixo. O desafio tem sido encontrar pessoas experientes que estejam dispostas a trabalhar em todos os aspectos da aplicação – que incluem CRUDs, relatórios etc. – e não somente na parte “legal” de infra ou interfaces avançadas.

Desta forma, perde-se um pouco o sentido de se ter pessoas só com o papel de arquiteto na equipe. Na verdade, cada um deve estar preocupado todo o tempo com as soluções dadas e participar de novas decisões, contribuindo com o resultado final do projeto. Acredito que este seja um modelo mais interessante, pois a ausência de um arquiteto formal faz com que os desenvolvedores se sintam mais livres para contribuir e assumam melhor esta responsabilidade. Claro que isto só é possível se cada desenvolver for capaz de contribuir desta forma e para isto, cada um deve de fato ser também um arquiteto!

Com isto, voltamos mais à maneira de como começamos, quando desenvolvíamos sozinhos. Se o sucesso que tínhamos lá puder ser refletido também nesta forma de trabalho em equipe, vamos estar no caminho certo!

, , , , ,

1 comentário