Archive for the ‘engenharia’ Category

Propostas de Trilha

Thursday, April 3rd, 2008

Recebi este e-mail esses dias (nome oculto por falta de permissão do autor):

[...]

Eu trabalho com Java a pouco tempo (desde maio de 2006), mas sempre procurei aprender bastante. Na época eu não conhecia nada, [...] não sabia Java a fundo[...] comecei num projeto que já tinha essa arquitetura de usar TO, BO, etc. e tal, e a partir dele comecei a aprender e abstrair, com isso acabei criando umas coisas que depois viraram o “framework das arquiteturas” da empresa, framework que segue aquela porcaria de lógica de negócio separado de dados. Não trabalho mais nessa empresa, e meu antigo analista me fala com orgulho que aquele framework que fiz já é base para 5 projetos, me deixa feliz e ao mesmo tempo preocupado. Hoje estou em outra, e faltamente com a responsabilidade de novo de definir a arquitetura dos projetos (não acho que tenha experiência suficiente
para isso, mas eu tento estudar ao Maximo e fazer o melhor), e dessa vez, o negócio é grande, pois a empresa é infinitamente maior.

Lendo as várias discussões que vocês têm no GUJ, bem como seu blog, eu tenho certeza que aquele framework era errado. Quando criei, ainda era dependente de tecnologias, muita coisa mudou, e no fim não era mais dependente de nenhum framework especifico, ele continha uns utilitários, as interfaces e algumas abstrações para serem implementadas e especializadas em cada projeto, mesmo assim não
consegui juntar os dados com a lógica.

Bem, juntar eu até consigo, mas ai não consigo mais imaginar um framework, perfeito, vocês falam que esse framework é, teoricamente, uma coisa ruim. Porem morrendo esse cara, todos meus programadores terão de programar o modelo sempre do zero, bem como saber programar
da forma certa (o que acredite em mim, acho que 80% das pessoas não fazem noção nem do que é a forma certa, quem dirá fazer, eu posso ser uma delas, mas pelo menos tenho noção de que da forma que esta feito, é errado), ai que volto a pensar em ter um framework para eles
estenderem e não precisarem se preocupar com tanta coisa.

Ai surgem minhas duvidas, para mim, seguir os conceitos de DSL, DDD, Fluent Interfaces etc. é algo que exige do programador um bom conhecimento, e eu não tenho muita experiência com bons programadores, a maioria se quer sabe a importância de uma interface, programa em
Java como se estivesse programando em C, como cobrar desses caras uns conceitos que nem eu entendo a fundo, ai volto a pensar naquele framework, que ao menos obriga eles seguirem algo dividido em camadas, fazendo eles separar a lógica de negocio do acesso aos dados, a lógica de negocio de cliente da lógica de negocio de fornecedor, enfim, consigo que pelo menos saia algo não tão feio, e que em eventuais manutenções consigo fazer de forma rápida.

Mas para mim isso é péssimo, porque não consigo evoluir, não consigo aplicar nos projetos as coisas que gostaria de aprender. Mas acho que a culpa é minha, porque em todo lugar tem programadores que devem não conhecer, e isso não pode ser um impeditivo.

Por isso, gostaria muito que você me indicasse livros, mas que seguisse uma ordem certa de aprendizado, o que eu preciso saber primeiro, depois e depois, eu não sei se eu devo começar lendo sobre a modelagem em si, ou conceitos DDD, DSL, sei la, queria apenas que você me guia-se recomendando links e principalmente livros.

Por exemplo, nesse tópico você deu exemplo de vários livros http://guj.com.br/posts/list/60/71466.java (na pagina 5 do tópico), qual seria o mais recomendado para iniciar, e depois, depois etc. [...]

Antes de mais nada eu diria que você está na trilha certa. A primeira coisa que um bom arquiteto deve fazer é se questionar o tempo todo, e justificar suas escolhas para si mesmo antes mesmo de alguém falar qualquer coisa.

Uma coisa que você precisa ter em mente é que o framework perfeito não existe. Quando discutimos design muitas vezes focamos no ideal, mas nem sempre o ideal deve ser implementado. Dificuldades tecnológicas são um grande fator, mas como você mesmo notou um fator muito importante é que arquitetura é sobre pessoas. Não adianta você ter a arquitetura tecnologicamente, perfeita, o design que melhor modela seu domínio e a maior performance possível se seus desenvolvedores não entendem ou não entenderão este zoológico.

Eu fui freelancer por um bom tempo, e nesse período não só eu era completamente verde sobre tecnologias bem como na época o acesso à informação era restrito (Internet só depois da meia-noite, lembra do pulso único?). Ainda assim eu tive que definir arquiteturas para alguns sistemas que duram até hoje, e aprendi bastante com isso.

Uma das coisas que aprendi é um clichê: Keep it Simple. Uma boa arquitetura, sofisticada ou não, é composta de primitivas arquiteturais bem definidas. Para entender essa afirmação pense na linguagem Java. A linguagem possui primitivas que giram em torno de objetos, definidos por classes que trocam mensagens através de métodos. Você não precisa de exceções à estas primitivas, consegue implementar tudo no seu sistema com elas. Assim deve ser sua arquitetura.

Se você ainda não tem conhecimento para utilizar conceitos mais rebuscados se mantenha simples e elegante -e elegante para mim significa ter boas primitivas e pouquíssimas exceções. Claro que sua arquitetura não vai servir para todas as coisas mas lembre-se que arquiteturas devem ser pensadas de acordo com o projeto, não existe arquitetura de referência.

Mas se eu não tenho uma arquitetura de referencia como confio nos meus desenvolvedores? Primeiro você deve contratar desenvolvedores bons, ou experientes ou com um bom potencial. Como falei diversas vezes neste blog entre 2005 e 2007 uns bons 40% do meu tempo foi dedicado contratando gente. O que eu aprendi nessa fase é que os bons desenvolvedores dificilmente vão caber no seu orçamento. Eles já são superstars em outras empresas. O que você precisa fazer é criar um time de pessoas eficientes, compromissadas e competentes. Este tipo de pessoa pode não ter a bagagem técnica necessária mas possui um potencial tão grande que você cria seus próprios superstars.

Mas se você não está contratando ninguém, como fica? Então você precisa é de gerencia de conhecimento. Muitas vezes eu já entrei num projeto onde as pessoas repetiam um mantra qualquer como “Não podemos fazer isso porque vai dar conflito com a rebimboca” o tempo todo e quando você pergunta ninguém consegue te explicar direito o que é a tal rebimboca ou porque ela cisma de conflitar com seu software.

Pense no seguinte: se as pessoas fossem ler por si só livros e bibliografias complicadas elas já teriam feito isso por elas mesmas. Se elas não procuraram para ter sucesso profissional elas não vão procurar apenas para entender seu software.

Criou uma arquitetura nova? Crie uma página no wiki da empresa (ou na Intranet, ou sei lá) contendo a descrição do que vocês fizeram. Não pense numa especificação de arquitetura, pense que você está escrevendo um artigo para um grande site sobre a arquitetura. O objetivo é criar algo útil e informativo. Organize sessões onde as pessoas troquem conhecimentos, talvez através de palestras ou de lighting talks ao menos duas vezes por mês.

E quanto aos livros? Recomendar livros depende muito do que você quer aprender. Eu não vou recomendar os livros neste post, vou tentar fazer algo mais abrangente e criar uma serie de posts chamados Proposta de Trilha. Eles vão conter uma bibliografia que eu ache interessante e na ordem que eu gostaria ter seguido. Imagino posts específicos para: Desenvolvedor, Arquiteto, Testador e Gerente de Projeto. Talvez mais, talvez menos.

Qi4j @ ThoughtWorks Community College

Thursday, April 3rd, 2008

Ontem tivemos mais um Community College na ThoughtWorks Melbourne, desta vez focamos no Qi4j.

É uma idéia interessante. Basicamente o qi4j (”quiforjêi”) usa micro-aspectos para modelar qualquer coisa. O problema é que a sintaxe atrapalha. Eles usam a Linguagem Java, com Language Adaptations e uma Factory mágica, provavelmente uma linguagem própria teria mais efeito.

Testadores Ágeis

Monday, March 24th, 2008

Todo mundo sabe que agilidade é sobre testes. Muitos testes. Bem, mais ou menos. Geralmente quando falamos de testes em metodologias ágeis estamos falando de testes escritos pelo desenvolvedor enquanto escreve código, e estes têm dois objetivos: feedback e bom design.

Feedback se consegue ao executar os testes. Quando você escreve uma classe que quebra um teste você sabe que existe algo errado imediatamente. Bom design se dá porque nada alem do necessário é criado, alem de que as tecnologias atuais de testes exigem que seu código siga alguns bons princípios para que seja testável, como bom gerenciamento de dependências.

Existe, entretanto, outro tipo de teste, geralmente feito por um profissional especializado, que chamamos de QA (Quality Assurance). Este teste valida o software de um ponto de vista diferente. Muita gente se engana achando que testes de desenvolvedor são suficientes para validar um sistema. Obviamente que assim como nem todo sistema exige um web designer profissional especializado nem todo exige um profissional de testes, mas a maioria dos projetos que já participei tinham nisso um benefício.

Estava lendo o artigo do Jeff Paton, ex-colega ThoughtWorker, sobre isso e lembrei das minhas experiências com testadores em time ágeis. Mas primeiro talvez seja melhor contar sobre as experiências em times não-ágeis.

Eu trabalhei em uma empresa muito interessante mas com um processo muito estranho. A empresa tem orgulho de usar waterfall para desenvolver seus produtos, ninguém está autorizado a escrever uma linha de código sem escrever 8 documentos. Obviamente todos os projetos atrasam e obviamente o software tem uma qualidade deprimente, mas eles conseguem fazer dinheiro neste cenário –ainda que pagando um preço muito alto.

Teste é uma coisa séria nesta empresa. Os produtos estão sujeitos à regulamentação de telecomunicações de diversos paises, e cada funcionalidade tinha que ser testada de acordo. O fluxo de desenvolvimento era o típico de waterfall, nós desenvolvedores criávamos nossos sistemas (programas em C++ para plataformas UNIX diversas) e enviávamos uma tag do Subversion para a equipe de testes. O testador teoricamente já lera todas as especificações funcionai do produto e já tinha os casos de testes escritos e, talvez, implementados.

Era aí que a brincadeira começava. Na melhor das hipóteses o testador encontrava um bug, rejeitava o pacote (usando um maravilhoso sistema interno desenvolvido em Lótus Notes) e enviava de volta. O desenvolvedor corrigia e o pacote era retestado. Isso nunca acontecia. O que acontecia era:

  • O pacote era aprovado. O desenvolvedor, com o sistema já em produção, olhava o plano de testes por curiosidade e via que eles não testavam absolutamente nada de relevante, ninguém garantia a qualidade do treco
  • O pacote era rejeitado. O desenvolvedor olha ao motivo da rejeição e via que o que estava sendo testado nem de perto era o que o sistema deveria fazer. O testador Não entendeu o documento, muitas reuniões explicando tudo novamente e o pacote era retestado sem modificações
  • O pacote era recebido pelo testador com total surpresa. Era uma aplicação de linha de comando e o testador esperava uma aplicação com interface web, ou o testador esperava que o sistema usasse banco de dados e ele mantinha tudo em memória, ou…
  • O testador rejeitava o pacote porque não sabia como testa-lo. O desenvolvedor não pensava no testador, o testador não pensava no desenvolvedor.

Claro que todos os membros do escritório de projetos (já falei que tínhamos CMMI?) sabiam a solução para estes problemas e é claro que para eles a solução passava pela criação de mais documentos, de 1 a 5 dependendo de quem você perguntasse.

Nas equipes ágeis que trabalhei a coisa era diferente. O testador senta ao lado do desenvolvedor, e por vezes eles trabalham em pair programming (pair testing, provavelmente). O testador está envolvido em todas as tarefas, validando que o que o analista de negócios pede é entregue, que confirma com as premissas do projeto e etc.

Para fazer isso ele está envolvido na elaboração das user stories e, principalmente, dos critérios de aceite definidos nela. Seu trabalho é verificar que os critérios de aceite são obedecidos pela implementação e que eles fazem sentido em primeiro lugar.

Um profissional come site perfil não pode ser simplesmente um usuário. Ele tem que conhecer sobre metodologia de testes de software (um campo enorme por si só), sobre o domínio do sistema e sobre desenvolvimento. Idealmente o testador é um desenvolvedor e sabe criar suas ferramentas. Um testador deve ser capaz de escrever seu próprio programa usando Selenium RC, ou suas fixtures no Fit.

Infelizmente nem sempre isso acontece. Em muitas empresas o cargo de testador é delegado à pessoas que possuem um conhecimento técnico muito baixo e executam tarefas do tipo “aperte o botão e verifique se quebra o layout”. Neste caso os desenvolvedores podem prover as ferramentas para os testadores mas ainda assim eles devem ter capacidade de escrever os casos de testes usando a ferramenta sozinhos.

O papel do testador não é dizer que a aplicação está homologada, na maioria das vezes isso é apenas uma ilusão que gerentes gostam de cultivar. O papel do testador é garantir a qualidade dele submetendo à testes rígidos. Não é um aceite formal, o testador não é quem aprova o software –o analista de negócios ou seu equivalente aprova o software- ele faz parte do desenvolvimento deste.

Minha experiência diz que assim como trabalhar com testadores apertadores-de-botão não agrega nada ao produto alem de burocracia desnecessária, trabalhar com testadores de verdade no time é uma das melhores coisas que pode acontecer num projeto de software.

No meu projeto anterior os testadores chegaram ao time apenas como apertadores de parafusos. Eles clicavam na tela e verificavam que a informação correta era disponibilizada. Como nossa participação no projeto era facilitar a adoção de metodologias ágeis isso tinha que mudar. A primeira coisa foi a participação dos testadores na definição das histórias, eles trabalham junto com o analista de negócios e o usuário definindo critérios. Eles também participam do sign-off da história –quando ela é apresentada aos desenvolvedores que vão executa-la- e quando conclui a história o desenvolvedor az um walkthrough dela para o testador. Em todas as etapas eles agregam informação, questionam as praticas e, principalmente, garantem que o software final é testável.

Foi adicionado ao time de facilitadores um testador especialista em automação –um desenvolvedor exercendo função de QA, basicamente-, a função dele era disponibilizar ferramentas e disseminar seu uso. Com o tempo desenvolvemos uma Internal DSL em Ruby para controlar nossa ferramenta de teste, o Selenium RC. A ferramenta é utilizada por desenvolvedores nos nossos testes de aceitação que fazem parte do build e pelos testadores na hora de dizer que uma história está concluída.

Os resultados desta adoção são excelentes. Quando nossa parte no projeto –facilitar a adoção das praticas- acabou a pessoas estavam aptas à continuar o bom trabalho por si mesmas. Os desenvolvedores ainda criam as ferramentas mas a gerencia, vendo os benefícios, agendou cursos de Ruby e Selenium para a equipe de QA.

Ainda bem que estou aqui

Friday, March 21st, 2008

Morar num pais distante é uma experiência diferente para cada um. Uma das coisas que estão bem claras para mim é que eu não estou fugindo do Brasil, estou apenas experimentando algo novo para ver como me sinto. No final deste experimento eu posso decidir ficar, voltar ou ir para outro lugar.

Esses dias eu pela primeira vez falei “ainda bem que não estou no Brasil”. A causa? A classe política brasileira que teima em se meter no que não entende.

A ACM é uma das mais respeitáveis organizações do mundo da tecnologia, uma referencia para toda a indústria. Há anos a organização estuda a possibilidade de aplicar licenciamento e regulamentação na área. A conclusão está neste documento, que diz:

From 1993 through June 2000 ACM worked with the IEEE Computer Society on projects to examine and guide the evolution of software engineering as a profession. This work was originally carried out under the Joint IEEE-CS and ACM Steering Committee for the Establishment of Software Engineering as a Profession. In 1998 the joint committee was superceded by the Software Engineering Coordinating Committee (SWECC) established by IEEE-CS and ACM to act as a “permanent entity to foster the evolution of software engineering as a professional computing discipline.” Under these efforts projects were launched to identify a software engineering body of knowledge (SWEBOK); develop curriculum recommendations for software engineering; and define a code of professional ethics and standards of professional conduct.

At the time SWECC was being established, the ACM and IEEE-CS received a request from the Texas Professional Engineers Licensing Board for help in defining performance criteria for software engineering licensing exams to be administered in Texas. As a result of this request, the question of licensing software engineers became more of an issue both for SWECC and for ACM. In March 1999 an ACM Advisory Panel on Professional Licensing in Software Engineering was established to make recommendations to ACM Council on the issue. After reviewing and discussing the advisory panel’s report (www.acm.org/serving/se_policy/report.html), ACM Council passed the following motion in May 1999:

“ACM is opposed to the licensing of software engineers at this time because ACM believes it is premature and would not be effective at addressing the problems of software quality and reliability.

“ACM is, however, committed to solving the software quality problem by promoting research and development, by developing a core body of knowledge for software engineering, and by identifying standards of practice.”

Over the next 12 months work continued on the SWEBOK project and other SWECC activities. In addition, ACM Council established two additional task forces: one to evaluate the SWEBOK effort; and the other to determine ways in which ACM and the profession might improve the robustness and quality of safety-critical software and evaluate licensing activities in this context.

After reviewing the reports of these two task forces, there was growing concern by ACM Council that supporting the request of the Texas Professional Engineers Licensing Board was becoming more the primary focus of SWECC’s efforts. As a result, ACM Council passed the following motion in June 2000:

“Society is becoming increasingly dependent on computers and software, which creates tremendous challenges and responsibilities for computing professionals. ACM Council believes that confronting these challenges will require creative and collaborative efforts by industry, universities, professional societies, and government. ACM Council strongly supports the idea of the ACM and the IEEE Computing Society working together on these challenges, including joint initiatives to promote the emergence of information technology professions.

“However, ACM Council believes that the current efforts of the Software Engineering Coordinating Committee (SWECC) toward licensing is misguided as they assume that software engineering is a profession appropriate for licensing under the rubric of the Professional Engineers Licensing structure and requirements. Moreover, ACM Council feels that further efforts in this direction will detract from our ability to take other more practical and productive initiatives needed to meet our common goals.

“Accordingly, Council directs that ACM withdraw from SWECC.”

Understanding the ACM Position

Why did ACM withdraw from SWECC? ACM Council felt the activities of SWECC had become too closely associated with promoting the licensing of software engineers as Professional Engineers (PEs).

Is ACM against licensing software engineers? Yes. For legal reasons, the only way to be a licensed software engineer is to become a PE. As described in the Safety-Critical report (see www.acm.org/serving/ se_policy/safety_critical.pdf), several topics on which all prospective PEs are tested, such as fluid mechanics and thermodynamics, are beyond the scope of software engineering. Mastering these topics could detract from the study of more relevant areas.

In addition, a software engineering license would be interpreted as an authoritative statement that the licensed engineer is capable of producing software systems of consistent reliability, dependability, and usability. The ACM Council concluded that our state of knowledge and practice is too immature to give such assurances.

Is ACM against software engineering being viewed as a profession? No. ACM believes it is important to foster the emergence of a true IT profession, not just software engineering. A field does not need licensing to be a profession.

Does ACM see a difference between licensing and certification? Yes. Certification is a statement by a recognized authority that a person is competent in an area. Licensing, by contrast, is regulated in the U.S. by legislation at the state level. With few exceptions, a PE in a profession for which licensing is required must be licensed in every state in which he or she practices.

Will ACM continue its efforts to improve the quality of software? Absolutely. ACM believes the problem of reliable and dependable software, especially in critical applications, is the most important problem facing the IT profession.

A Sociedade Brasileira de Computação (SBC) é outro organismo importante na indústria. Ela também já flertou com a regulamentação mas possui a seguinte opinião:

A comunidade científica da computação brasileira vem discutindo a questão da regulamentação da profissão de Informática desde antes da criação da SBC em 1978.

Fruto dos debates ocorridos ao longo dos anos, nos diversos encontros de sua comunidade científica, em relação às vantagens e desvantagens de uma regulamentação da profissão de informática, a SBC consolidou sua posição institucional em relação a esta questão pela formulação dos seguintes princípios, que deveriam ser observados em uma eventual regulamentação da profissão:

1. Exercício da profissão de Informática deve ser livre e independer de diploma ou comprovação de educação formal.
2. Nenhum conselho de profissão pode criar qualquer impedimento ou restrição ao princípio acima.
3. A área deve ser Auto-Regulada.

Os argumentos levantado junto à comunidade da SBC e que nortearam a formulação dos princípios acima estão detalhados na Justificação que acompanha o PL 1561/2003, o qual é integralmente apoiado pela Sociedade de Computação.

O livro Software Craftmanship, de Pete McBreen, possui um capítulo chamado “Licensing is an Illusion”, de onde eu cito:

Licensing Is an Attempt to Solve the Wrong Problem

Licensing works for engineering because one licensed engineer can certify that something using accepted best practices has been built. The same is not possible with software. Certification can be applied to buildings and other mechanical structures because they involve standard materials and designs with well-known properties. They are also a lot less complex than software. Most engineering designs have very few parts. For example, cars typically have fewer than 15,000 parts and fewer than 5,000 unique part numbers. By comparison, this book contains about 50,000 words, and the space shuttle software contains approximately 420,000 lines of code.

Cars are interesting because they are so complex that it is not cost-effective to have licensed engineers certify that they are built correctly. As the J.D. Power and Associates 2000 Vehicle Dependability Study reported, even the best cars average more than two defects per vehicle. Some cars have serious design defects that require a complete safety recall, attesting to the fact that even the design is incorrect. Tellingly for the engineering profession, auto manufacturers rarely acknowledge a problem until they have a fix available.

In software, the problems are even harder. Even with multiple reviews and copyediting, most books contain a few typos or mistakes. Now imagine the problem that a licensed software engineer would face when asked to sign off on the space shuttle software. An individual could not sign it off as correct. Even if a person spent an entire career at that one task, she could never sign it off as correct because the software is too large and complex for any one individual to be able to guarantee that there are no mistakes. The concept of a single, responsible engineer signing off the complete work is not feasible for software.

The key problem is that licensing assumes that it is possible to inspect quality into a product. This approach is the wrong way to improve quality, and even the manufacturing world has shifted away from this concept.[41] As quality pioneer W. Edwards Deming stated, one of the key responsibilities of management is to cease dependence on mass inspection and testing: much better to improve the process in the first place so you don’t produce so many defective items, or none at all.

Eu pergunto se o senador Eduardo Azeredo tem respostas para estes questionamentos. Pergunto se ele e os envolvidos e apoiadores deste grande erro sequer sabem que existe um mundo todo aqui fora e que o Brasil não é o primeiro a passar por este questionamento. Pergunto se eles sabem que nenhum pais minimamente relevante na área de Tecnologia da Informação, desde os desenvolvidos até nossos colegas de BRIC impõe uma lei absurda dessas.

Mas nós sabemos como o Brasil funciona (funciona?) e que essa lei não vai causar nada alem de transtornos leves. Não posso mais chamar a pessoa de Analista de Sistemas (que aliás é algo que nem existe mais hoje em dia) mas podemos continuar tudo como sempre foi.

A diferença, é claro, é que mais e mais pessoas vão entrar em instituições de ensino de péssima qualidade apenas para ter o diploma que dá direito ao exercício de uma profissão que não existe. E eu pergunto: a quem esta lei beneficia mesmo? Os profissionais ou os donos de faculdades McDonald’s?

Sinal de Vida

Wednesday, March 12th, 2008

Nossa, tanta coisa que nem sei o que postar. Neste tempo que fiquei afastado –quase um mês!- juntei um bando de idéias para postas mas agora falta tempo.

Neste período terminei mais um projeto. Estou alocado no mesmo cliente e temos dezenas de pequenos projetos que fazem parte de um projeto maior que faz parte de um projeto tão gigantesco que toda semana tem uma festa para comemorar que alguém lá em Perth terminou uma parte que você nem sabia que existia. Segunda-feira devo ser movido para outra parte, desta vez é apenas para prestar ajudar um grupo de desenvolvedores do cliente que está com problemas num sistema baseado em mensagens assíncronas. Deve durar até Maio, creio.

Mas não é o trabalho que me tem afastado, pelo menos não é o maior causador. O problema é a minha pesquisa. Eu tenho dedicado boa parte do meu tempo livre a me aprofundar nos assuntos necessários para uma boa compreensão de Language-Oriented Programming e Domain-Specific Languages.

Infelizmente existe duas áreas de Ciência da Computação nas quais eu nunca me interessei muito: linguagens de programação e inteligência artificial. IA é algo que eu ainda não estudo mas para entender DSLs uma das coisas mais importantes é entender como as linguagens são criadas. Isso está me fazendo tentar aprender em um mês o que eu negligenciei por anos, incluindo a leitura capa-a-capa do SCIP. Eu sei um pouco de Common Lisp mas ainda que não soubesse não seria problema, o livro usa Scheme mas você não precisa saber Scheme ara começar a ler –bem no estilo de Bertrand Meyer que ensina Eiffel no seu livro de OO.

Depois disso vem o Concepts, Techniques, and Models of Computer Programming - que é uma recomendação do Rafael- e The Seasoned Schemer. For a as dezenas de papers da ACM que tenho pesquisado.

É trabalhoso, é complicado mas é uma das coisas que me fizeram vir ara a Austrália e mudar de emprego. Na ThoughtWorks eu tenho acesso a um material seleto sobre iniciativas no mundo real destas tecnologias, e acesso à pessoas com um conhecimento sobrenatural sobre este assunto. Apesar de eu adorar fazer parte de um time fixo desenvolvendo um produto e focado em melhoria, trabalhar como consultor me dá mais liberdade para focar no meu interesse atual, que em grande parte é essa pesquisa. Eu trabalho de 9 as 17h no cliente -sem hora extra- levanto da minha mesa e em 15 minutos estou no meu apartamento.

Antes que comecem as especulações entre meus três leitores não, eu não pretendo fazer nada de útil com o resultado da pesquisa. O resultado, na verdade, não importa, para mim importa o que eu aprender no caminho.

Se tudo der errado eu faço uma aplicação em Lisp pro Facebook e fico rico :)

Gerenciando Débitos

Sunday, February 17th, 2008

Todo projeto que já participei, dos meus pet-projects até os com equipes imensas, possuem algum nível de tech debt. Sempre a mesma história: não temos tempo para isso agora, na próxima oportunidade corrigimos.

O problema é que em muitos casos o acúmulo de coisas que deixamos pelo meio do caminho é prejudicial à saúde do projeto. Mais que preciosismo de nerds e perfeccionistas, tech debt pode –e geralmente vai- atrasar o andamento do time.

Nos projetos que eu gerencio eu gosto de alocar um orçamento para resolver estes problemas. Durante o planning game eu deixo claro que precisamos resolver problemas enquanto estamos implementando funcionalidades e geralmente aloco alguns pontos na iteração para eles, normalmente algo perto de 20% do trabalho. Normalmente eu aceito que estas histórias técnicas tenham prioridade baixa e no geral tudo ocorre bem.

Se temos uma emergência então eu costumo não ser muito flexível em relação à solução do problema. As histórias técnicas neste caso ganham prioridade máxima dentro da iteração.

Como geralmente o cliente está satisfeito com a velocidade da equipe num processo ágil (se não está temos outro problema) quando sobra –e quase sempre sobra- tempo extra numa iteração geralmente eu preencho com tech debt, e em especial deixo os desenvolvedores priorizarem o que querem fazer. Muitas vezes não dá tempo para fazer homologação destas mudanças durante a iteração vigente e elas acabam indo para produção apenas na iteração posterior, mas é uma boa estratégia.

O que importa é não deixar o tech debt acumular. Se você tem duvidas dos problemas que o acúmulo de histórias técnicas causam basta lembrar a última vez que você entrou em um projeto para dar manutenção em um sistema pré-existente. Eu nunca vi um caso onde o sistema antigo não tenha toneladas de problemas causados por “deixar para depois” mudanças que não eram urgentes mas foram crescendo em urgência com o tempo.

E claro que meu projeto atual não é diferente. Trata-se da conversão de boa parte de um sistema legado em Java para Ruby (não Rails, Ruby). Como todo projeto deste tipo o orçamento não contempla uma reescrita do sistema, apenas uma conversão. Isso quer dizer que se um módulo assovia e chupa cana em Java ele, teoricamente, vai assoviar e chupar cana em Ruby.

O bom de trabalhar em um time ágil é que não é porque no início do projeto não se pensou em melhorar as coisas que isso precisa ser verdade até o fim dele. Após a equipe (desenvolvedores, analistas de negócios e gerente de projetos) percebemos que alguns itens realmente estavam atrapalhando o andamento do projeto. Nossos dias estão cercados de tarefas repetitivas que existem apenas para contornar alguma “gambiarra” que o sistema original tinha e nós estamos reproduzindo de maneira burra. Levamos a questão aos clientes e fizemos entender que se gastarmos alguns pontos nestas tarefas em algumas iterações nossa velocidade irá aumentar, e muito.

Apos conseguirmos 25% dos pontos de uma iteração para histórias técnicas veio a questão: temos dezenas de problemas, o que faremos primeiro? Como é um time grande cada um tem seu ponto de vista sobre o que está errado e o que precisa melhorar, então fizemos da maneira ágil: disciplina e flexibilidade.

Marcamos uma reunião com o time e coletamos em cartões todos os problemas que conseguíssemos pensar. Os cartões foram pregados na parede, divididos entre coisas do dia-a-dia e coisas que realmente indicam a visão que o sistema deve tomar, aspectos arquiteturais.

14022008446.jpg

Depois cada um recebeu 5 votos para distribuir entre os cartões. Quase todas as histórias eram importantes então precisamos limitar o numero de votos para entender o que realmente é critico.

14022008445.jpg

Apos este exercício nós criamos um backlog paralelo para o produto, apenas com histórias técnicas. Este backlog foi estimado e baseado nele o time decide que história técnica entra nos 25% de pontos disponíveis.

13022008442.jpg

Uma das vantagens dessa abordagem já foi percebida. Nosso sistema é um fluxo de operações em sequência. Operações em sequência são uma ótima área para programação procedural e isso fez com que os desenvolvedores originais do sistema seguissem este paradigma.

Claro que quando se mistura uma linguagem orientada a Objetos com código procedural é necessária muita cautela, e a maioria das pessoas acha que para o código ser procedural basta usar atributos públicos nas suas classes. Existem muitas métricas para qualidade de código procedural (a maioria das métricas de código OO são evoluções ou adaptações destas, na verdade) e nosso código não seguia nenhuma.

Aproveitando o nosso orçamento para histórias técnicas nós introduzimos um sistemas de jobs, uma implementação do padrão Chain of Responsibility. Até agora 50% das funções já foram convertidas para o modelo novo e a cada iteração mais são convertidas.

O resultado das ultimas iterações mostra um aumento consistente de 10% na velocidade. Todos os envolvido creditam esta melhoria à mudança e ainda estimamos que quando todo o sistema for convertido para a nova arquitetura teremos por volta de 25% de aumento total.

Existem coisas simples que podem decidir se um projeto vai ser um sucesso ou fracasso. Não esconder sujeira debaixo do tapete é uma delas.

Entrevista sobre Domain-Specific Languages

Tuesday, January 29th, 2008

O Laércio Queiroz me entrevistou sobre DSLs. O resultado você vê no blog dele.

Você Pergunta: RAD

Thursday, January 24th, 2008

Uma pessoa me escreveu um email sobre o tópico anterior. Novamente não vou citar nomes porque não pedi permissão (e não tenho motivos para expôr esta):

Shoes, beleza cara?

Então, lendo sobre a discussão sobre o Maker eu cheguei no seu blog e li sobre RAD.
Aquela ferramenta no NetBeansLixo pra fazer GUIs é um RAD? Ele desenvolve parte de um software, eu sei, não é um modelo de processo de desenvolvimento, né??

Enfim, acredito que existam mais algumas por aí como Maker e queria saber da sua opinião: todas essas ferramentas são RADs e todas elas cometem gafes? Onde quero chegar é na pergunta: Hoje em dia, SEMPRE teremos um desenvolvedor por trás da solução?

É que eu sou totalmente contra essas ferramentas de gerar códigos automáticos… não confio muito nessas coisas… prefiro eu mesmo fazer os códigos, mas tenho a dúvida: estou muito antiquado (no sentido de muito atrasado e não acompanhando as tecnologias que estão evoluindo hoje) ou estou no caminho correto?

Bom, se você respondeu que sim na primeira pergunta (do NetBeans sobre GUIs), a principal desvantagem das ferramentas RAD (se é isso que aquele Lixo é) é a manutenção e evolução, certo? Uma vez, fazendo um trabalho pra faculdade, tive que usar aquele NetBeans. Quando fui usar Refactoring… nossa cara, que coisa mais chata… tive que refazer praticamente toda a interface gráfica.

Abraço.

Apesar de usar, eu odeio o termo RAD. Ele significa um grupo enorme de coisas e ao mesmo tempo não significa nada. O livro Software Development: Building Reliable Systems define RAD:

For the last ten years, many software projects have incorporated the use of “Rapid Application Development” methodologies in an effort to decrease development times. RAD, as it is generally referred to, incorporates an umbrella of methodologies based on spiral, iterative development technologies. RAD techniques range from the simple use of GUI development tools to quickly build prototypes, to processes incorporating complete, cross-functional business analysis. [...]

Então vou considerar que você quer dizer por RAD “ferramentas geradoras de código” do contrario este post nunca vai acabar. Sim, o Matisse do Netbeans é uma ferramenta geradora de código.

Ferramentas geradoras, em geral, são úteis quando não querem dominar o mundo. Eu adoro quando o Hibernate ou o Rails gera meu DDL SQL e eu não tenho que escrever CREATE TABLE. Eu adoro quando o Eclipse gera meus getters e setters e coisa do tipo. O problema é que esses geradores não costumam sobreviver num projeto de verdade.

O grande problema do gerador de código padrão, como o citado, é que ele possui diversos vazamentos de abstração. O Joel Spolsky fala especificamente sobre geradores:

The law of leaky abstractions means that whenever somebody comes up with a wizzy new code-generation tool that is supposed to make us all ever-so-efficient, you hear a lot of people saying “learn how to do it manually first, then use the wizzy tool to save time.” Code generation tools which pretend to abstract out something, like all abstractions, leak, and the only way to deal with the leaks competently is to learn about how the abstractions work and what they are abstracting. So the abstractions save us time working, but they don’t save us time learning.

Como pode-se perceber pelas discussões citadas o mercado destas ferramentas é… complicado. Um desenvolvedor que entende como a plataforma funciona (Java EE, no caso) dificilmente se encantaria pela ferramenta. Ele pode utilizar algo como um Spring IDE para gerar arquivos de configuração mas sabe que isso não é tão simples assim.

Os programadores mais recentes na plataforma Java podem não ter consciência disso mas uma ferramenta chamada xdoclet era muito usada quando sofríamos diariamente com EJBs 2.1. O que o xdoclet faz é gerar código, ele gerava todo o mapeamento do EJB (uns 3 arquivos XML diferentes, pelo menos) a partir de anotações JavaDoc (não existia Java 5 naquela época). O xdoclet era a salvação da lavoura, conseguia abstrair muitos problemas mas.. não era perfeito, nem pretendia.

Eu já trabalhei em projeto onde 50% do código era gerado pelo xdoclet e do restante ele não dava conta. A ferramenta não possui o tal do round-tripping então não dava para misturar código gerado com modificado. A solução foi optar por uma arquitetura que isolava as duas partes em módulos diferentes e só conseguimos chegar até ela porque –como disse o Joel- sabíamos como a ferramenta funcionada. Essa é uma ferramenta de automação, não de “geração automática de sistema”. Ela automatiza o trabalho que você teria, não te livra do fato de conhecer o que… bem… é sua profissão.

Acho que o Matisse se enquadra neste tipo.

O problema é que essas ferramentas –e seus persuasivos vendedores- dizem que irão abstrair todo o desenvolvimento. Para os cenários ideais elas podem fazer todo o prometido mas não houve até hoje uma ferramenta que conseguisse real sucesso fora dos casos mais simples e isso porque não é assim que construímos sistemas hoje. Nossos sistemas são uma salada de linguagens, conceitos, mapeamentos e configurações que uma ferramenta deste tipo não consegue acompanhar.

O que geralmente elas fazem é te prender à uma ou algumas arquiteturas genéricas que servem razoavelmente para alguns casos -geralmente sitezinhos CRUD de intranet- mas não para todos ou sequer para a maioria. Como arquitetura não é commodity não se pode simplesmente aplicar a mesma estrutura em todos os cenários.

Apos algum tempo em TI você começa a entender que o dia-a-dia desse mercado é um grande “mais do mesmo”. Você sempre está criando as mesmas coisas. Da última vez que contei eu já tinha criado uns sete gerenciadores de conteúdo web. Dá para utilizar a mesma arquitetura em todos? Não. Uns eram simples formulários, outros se integravam com back-ends complicados, outros era assíncronos, outros tinham integração com legado… cada um tinha uma história. Se há oito anos atrás eu comprasse uma ferramenta dessas e a tivesse aplicado nestes projetos eu teria que fazer personalização (i.e. sair do maravilhoso mundo do fluxograma) a cada projeto.

Mas eu estou falando de desenvolvimento de software de um tipo, não do mercado todo. Quando estive na faculdade pela última vez (antes da segunda fuga) estudei com uma pessoa de 43 anos que desde os anos 80 vive fazendo software em coisas como CLIPPER para lojinhas e boutiques. Ele não ganha mal. Pelo que entendo dos softwares deste tipo (já trabalhei neste ramo) a arquitetura é quase sempre a mesma. Talvez ele se favorecesse de algo assim nos seus negócios, apesar de que eu ainda acharia um risco desnecessário.

Então sim, hoje precisamos de desenvolvedores para projetar um sistema. Desenvolver sua arquitetura, seu design e verificar para que tudo seja eito da maneira mais adequada para o projeto (que nem sempre é a técnica mais adequada). Mas e o futuro?

O futuro prevê o uso de ferramentas de um nível mais alto, mas de maneira diferente. O ponto crucial é que essas ferramentas não são geradores de código Java (ou C#, ou Ruby ou o que for), elas mudam a visão sobre o código. Ferramentas como Domain-Specific Languages aumentam o nível da linguagem não tornando-a mais abstrata apenas mas sim levando para perto do negócio. Ferramentas de visualização criam pontos de vista diferenciado sobre o mesmo artefato, dependendo de com que olhos se enxerga.

Tudo indica que para desenvolver softwares no futuro o desenvolvedor não terá o mesmo papel que tem hoje. Ao invés de criar o código do sistema em si iremos criar as ferramentas que dão suporte à criação de sistemas pelos usuários.

Seja qual for o futuro ele não é sobre gerar código. Isso nós já fazemos à décadas e serve apenas como quebra-galho para nos livrar da complexidade que nós mesmo criamos.

Programação RADioativa

Sunday, January 20th, 2008

Há alguns anos, quando era consultor independente, eu fui chamado por uma empresa bem grandinha do ramo de telefonia. Eles tinham produtos em C++ e queriam migrar para o Java. Na verdade já haviam migrado, mas estavam com problemas.

A primeira tentativa deles foi transferir toda a parte gerencial do sistema -que era vendido por alguns milhões de Euros- para Java. Para fazer esta etapa eles haviam contratado há um ano uma consultoria especializada canadense. Os canadenses sugeriram a compra de uma ferramenta RAD -por um acaso de outra empresa canadense- que permitiria que os desenvolvedores C++ criassem a aplicação em pouco tempo. Em três meses, tempo recorde, a aplicação já estava rodando no cliente, em produção. Durante os testes eles verificaram que a coisa era muito lenta mas como o mercado de telefonia tem muito dinheiro eles simplesmente aumentaram o número de máquinas.

A coisa foi passando até que alguém foi fazer a primeira manutenção. O sistema era um grande catálogo de assinantes, dependentes e registros de ligação, as regras pesadas mesmo ficavam no sistema em C++. As primeiras manutenções foram correção de bugs. A ferramenta funcionava dentro do Eclipse, você definia um modelo de entidades parecido com o modelo relacional, depois dizia quais operações precisava (criar, ler, listar, etc.), isso gerava o código. Se você precisasse de uma regrinha de negócio diferente, digamos que cada vez que um novo cliente fosse adicionado alguém recebesse um email, ia ter que alterar o código gerado. Como a aplicação -como todas- tinha suas peculiaridades muito código era escrito a mão. Mesmo assim o ato de criar toda a infra-estrutura (o scaffolding) poupava muito tempo.

Qual não foi a surpresa quando alguém reparou que a ferramenta só gerava código, ela não o lia de volta? Se você alterar o código e fizer alguma alteração o fornecedor deu duas escolhas:

  1. Alterar o código usando a ferramenta gráfica, regerar o código e depois adicionar novamente nossas alterações
  2. Abandonar a ferramenta e fazer tudo no código

Neste ponto que eu fui chamado. O fornecedor sugeria fortemente a segunda opção, por incrível que pareça. Eu concordei com eles, recomendei ao cliente que assumisse o prejuízo de ter escolhido uma ferramenta ruim e refatorasse o sistema enquanto inseria novas funcionalidades.

O mundo adora ferramentas RAD. Elas provocam a ilusão de que você não precisa de conhecimento ou de um profissional para criar programas. Não é assim que a banda toca.

Essas ferramentas surgem todos os anos. Todos se dizem revolucionários, quase nenhum diz que é um gerador de código, e todos dizem que servem para 87% dos casos. Puro marketing.

Geradores deste tipo existem há décadas. É até engraçado que o mais novo representante desta leva se gabe de ‘revolucionar’ usando o conceito de programação visual por fluxograma. Ahm? Isso existe praticamente desde que surgiram IDEs gráficas. Qualquer coisa que gere código via UML vai ter um fluxograma. A diferença é que não vai ter só fluxogramas, exatamente porque essas coisas foram abandonadas.

Na UML utilizamos o diagrama de atividades para um fim muito específico: representar transição entre estados dos objetos. É um dos diagramas mais raramente utilizados em um projeto OO simplesmente porque ele é procedural demais. Um sistema OO foca na interação entre objetos, não em algoritmos em si -que estão encapsulados dentro dos objetos.

Ao utilizar um fluxograma como unidade principal do seu sistema você está abandonando a OO. Isso pode ser uma coisa boa, depende do caso. para sistemas genéricos décadas de pesquisa da indústria apontam que Orientação a Objetos traz os melhores resultados na modelagem de negócios. Para um caso específico (BPM por exemplo), fluxogramas podem ser melhor. Estas ferramentas vendem trinta anos de retrocesso em modelagem.

Ainda assim, elas oferecem um bom scaffolding, não? Você não precisa saber nada sobre arquitetura, basta gerar o código na ferramenta! Bem, não exatamente. A maioria destas ferramentas vai seguir o exemplo acima: possuem poucos pontos de extensão e quando possuem não conseguem se integrar a eles. A primeira pergunta a fazer para um fornecedor desses é se a ferramenta suporta round-tripping. Round-tripping é o ato de gerar o código na ferramenta, editar o código e a ferramenta ser capaz de lidar com o código alterado. Quase nenhum RAD possui esta característica.

Outro problema é a arquitetura. Eu tenho certeza que uma arquitetura web simples pode ser utilizada por 87% dos casos mas tenho mais certeza ainda que cada um destes casos vai evoluir de uma maneira diferente. A arquitetura tem que ser flexível o suficiente para permitir todas estas formas de evolução. Obviamente que nenhuma destas ferramentas oferece nada parecido. Nós já vimos antes sobre o problema de se estabelecer uma arquitetura única para tudo, o problema com estas ferramentas é muito pior. Quando se define uma única arquitetura para todos os sistemas de uma empresa é ruim mas o que estas empresas estão vendendo é uma arquitetura única que funcionaria em diversos tipos de aplicações de diversos domínios sem sequer saber as necessidades delas antes.

Infelizmente em busca do cálice sagrado as empresas e -pior ainda- governos vão continuar gastando dinheiro nestes engodos. Eles prometem inovação mas fazem retrocesso de três décadas no tempo. Como conseguem montar um CRUD em 30 minutos são vendidos como a última bolacha do pacote, e lá vão os gerentes desinformados comprar estas coisas.

Se você está procurando este tipo de ferramenta esqueça qualquer um desses produtos ‘revolucionários’. Para começar entenda que a Ciência da Computação ainda não tem uma resposta definitiva para você. Sinto muito, estamos trabalhando nisso (é uma das partes da minha pesquisa). O campo mais avançado nesta área chama-se MDA. Eu não acredito em MDA mas isso não me faria negar que ela é a proposta mais plausível para este tipo de ferramenta atualmente. MDA possui implementações livres e proprietárias, é um padrão do OMG, utiliza UML, é baseado em um conceito de transformação de modelos e não de geração de código, é extremamente extensível e pode ter as características de produtividade dessas ferramentinhas de garagem. Só não baseie sua estratégia nele.

Os problemas de MDA: (1)ele eleva o nível de abstração mas não gera programação intencional e (2)ele usa uma ferramenta que não foi criada para isso, UML. São problemas muito menores do que os que você vai enfrentar com estes softwares ‘revolucionáros’ de ‘programação por fluxograma’.

Não caia no conto do vigário.

Engenharia de Build

Tuesday, January 15th, 2008

Eu já trabalhei em projetos com vários tipos de sistemas de build. Uns usam um build completamente automático, uns usam um build interativo (um jeito carinhoso para se referi à porcaria do build em que você tem que apertar ‘enter’ constantemente). Uns demoram 1 minuto ou menos, outros 59 minutos. E alguns nem sistema de build criam! Acham que usar a função ‘Export as JAR’ da IDE é algo aceitável (dica: não é).

A maioria dos projetos tinha ma coisa em comum: não levavam o build a sério. O build de uma hora que mencionei começou com segundos e passou para minutos em algum tempo. Lembro numa reunião onde um grupo de desenvolvedores levantou a questão de que estávamos chegando em 30 minutos, todos na empresa ficaram preocupados. Aí a coisa esfriou e ninguém fez nada, nem ninguém reparou quando esse build chegou em uma hora.

A primeira medida aplicável é tratar o build como parte do seu software, como seu código. Praticamente todos os grandes projetos que participei tinham builds desnecessariamente complexos. Já vi casos onde arquivos build.xml eram gerados on-the-fly através de transformações XSTL, já vi empresas com frameworks de build, onde seu build.xml tem que importar um build.xml criado pela sempre infame ‘equipe de arquitetura’, já vi builds que usam Mavem como se fosse ant e até mesmo um build.xml que usava AWK para fazer a maioria das coisas. Tudo isso é mau sinal.

Seu build deve ser simples. Rake, ant, maven, make não importa: simples. Arquitete-o como faria com sua aplicação: divida em módulos e crie um arquivo de build para cada módulo. Idealmente deve ser possível fazer o build de um módulo em isolamento. No topo, crie um arquivo que faz o build de toda a sua aplicação apenas chamando os builds de cada módulo. Pense na interface dos seus builds, nos parâmetros de entrada e de saída. Encapsule seus módulos.

Testes unitários devem ser executados imediatamente após a compilação (se existente). Se o build falhar porque o teste unitário não passou é melhor que isso seja rápido e não após gerar o pacote de instalação. Testes de integração rodam após esse e os de aceitação na sequência.

Cuidado com testes de aceitação e integração. Pense no que você está testando, já vi casos onde a maioria dos testes de aceitação apenas repetia o que os testes de integração já faziam. Não esqueça que o papel dos testes de desenvolvedor não é substituir a homologação, você como desenvolvedor testa em caixa-branca e sabe quando um teste substitui o outro

Mantenha os artefatos gerados em diretórios temporários até que sejam copiados para seu destino final. Não misture artefatos temporários (arquivos .class soltos, por exemplo) com artefatos versionados (código-fonte). Use os .cvsignore da vida com sabedoria.

Pense sempre no desenvolvedor novato. Quanto tempo o novato precisa para ter um build funcionando na máquina dele? Se a resposta for mais que uma hora você precisa refatorar o build. Convencer os analistas de negócio e clientes que o build deve ser refatorado é duro. Provavelmente é a parte do código onde eles menos vêm valor. Antes de usar a força (ou a clandestinidade) para fazer suas mudanças tente ter uma conversa séria, tente msotrar o valor preto-no-branco.

O build de 60 minutos citado era um problema real. Enquanto o CruiseControl executava o bichinho o desenvolvedor tinha que ficar de braços cruzados porque poderia haver um problema n o commit dele e ia ser bem ruim identiicar o que houve se ele continuasse alterando o fonte. Também, após 60 minutos já haviam vários outros commits na fila, o próximo build levaria mudanças de muitas pessoas diferentes. O assunto era levantado requentemente para o ciente, que ignorava.

A solução que nosso time deu foi interessante. Começamos a escrever em um mural tempo que perdíamos com o build. Em algumas semanas descobrimos que pelo menos 8 horas de deenvolvimento por dia eram perdidas no processo. Fizemos uma estimativa de quanto de código poderia ser entregue usando essas horas desperdiçadas e fomos conversar novamente com o cliente. A postura foi outra, vendo os números as pessoas começam a dar valor. Conseguimos 8 horas por semana para trabalhar no build, o que ez com que ele reduzisse para 30 minutos. Não é o ideal, pelo contrario, mas 30 minutos a menos já foi suficiente para entregarmos mais valor e, principalmente, levantar a moral das pessoas.