Porque adoramos ser genéricos ?

September 3rd, 2008  |  Published in Arquitetura, programação

Passamos a maior parte do tempo desenvolvendo programas que devem ser, além de compatíveis com a arquitetura atual do sistema, estar preparados para futuras alterações. Geralmente somos levados a acreditar que, como programadores, nossas implementações devem ser “genéricas” e “atemporais”.
Essa busca pelo “genérico” não é incomum entre arquitetos e programadores. Kevlin Henney já falou a respeito desse comportamento:

A common problem in component frameworks, class libraries, foundation services, and other infrastructure code is that many are designed to be general purpose without reference to concrete applications. This leads to a dizzying array of options and possibilities that are often unused, misused, or just not useful. Most developers work on specific systems: the quest for unbounded generality rarely serves them well (if at all). The best route to generality is through understanding known, specific examples and focusing on their essence to find an essential common solution. Simplicity through experience rather than generality through guesswork.
Kevlin Henney

Acho que essa cultura de generalização exagerada pode criar problemas quando programadores perdem o foco no contexto do sistema, nos interesses dos stakeholders e passam em se preocupar em produzir frameworks e componentes genéricos.

Although many architects value generality, it should not be unconditional. People do not on the whole pay for (or need) generality: They tend to have a specific situation, and it is a solution to that specific situation that has value. We can find generality and flexibility in trying to deliver specific solutions, but if we weigh anchor and forget the specifics too soon, we end up adrift in a sea of nebulous possibilities, a world of tricky configuration options, overburdened (not just overloaded) parameter lists, long-winded interfaces, and not-quite right abstractions. In pursuit of arbitrary flexibility you can often lose valuable properties, accidental or intended, of alternative, simpler designs.
Kevlin Henney

Thus, the real goal for all architect is to make sure the final architecture, resulting from the design and code written, solves the stakeholders concerns. I have nothing if only nice code and a great design that does not solve the stakeholders needs.The architect needs to learn how to get out of the design/coding swirl without losing eye-contact, and start developing the solution with the problem in mind.
William Martinez Pomares

A maioria dos esforços para tornar implementações genéricas, acabam inserindo complexidade desnecessária ao código fonte, pois as decisões são feitas para resolver, problemas que na maioria das vezes acabam não se concretizando no futuro.
Frameworks genéricos, ou frameworks de referência geralmente se tornam um problema de arquitetura de sistemas. As boas arquiteturas são estabelecidas dentro de um cenário espefício. Cada projeto tem característias e necessidades únicas, que podem ser resolvidas com frameworks mais apropriados para àquela situação. Mas na prática, o que acaba acontecendo, é que após um projeto bem sucedido, muitos programadores tem a impressão que o mesmo framework pode ser utilizado para qualquer outro projeto futuro. E então, a máxima torna-se verdadeira: pra quem só tem um martelo, todo problema é prego.

Claro, que práticas que já obtiveram sucesso num projeto, podem eventualmente ser aplicadas em outras situações. Contudo, isso não pode se tornar uma regra. Achar que algumas tecnologias podem ser aplicadas em todos os projetos, é ilusão. Mas tem muita gente que ainda acredita em soluções genéricas, compra meias tamanho único e fica na eterna busca pela bala de prata para seus problemas.

A busca pela bala de prata...

Além do mais, o cliente não compra arquitetura. O cliente paga por uma solução, que as vezes, é software. O cliente não está preocupado com o número de camadas da aplicação ou se ela foi desenvolvida com struts ou mentawai, muito menos com o design de suas classes. O cliente espera que o sistema ajude a resolver seus problemas e venha de encontro aos seus anseios.
Apesar da arquitetura de sistemas estar mais relacionada à escolha e aplicação de tecnologias, creio que seja fundamental que arquitetos e programadores sempre mantenham foco nos interesses e objetivos dos principais stakeholders dos projetos.

E antes de sair tentando reusar objetos e generalizar componentes, pergunte a si mesmo: “O que realmente precisa ser feito ?”

Os 10 mandamentos para controlar o seu égo

August 23rd, 2008  |  Published in diversos, programação

Apenas pense, se você já não passou por uma situação parecida:

programador jr: estou fazendo uma alteração nesta classe, o que você acha de…
programador ego senior: Eeiiii.. eu implementei esta classe !!!  Porque você está mexendo nisso agora ?!?!?!”

Na maioria dos projetos que participei, enfrentei muitos problemas técnicos. Mas nenhum destes problemas,  foram tão desgastantes, como os conflitos de relacionamento dentro das equipes. As vezes, os égos das pessoas se tornam maiores do que o próprio projeto, e isso, definitivamente não é bom.
Sobre o esse tema, não posso deixar de citar um artigo bem interessante que havia encontrado já fazia algum tempo no builder.com. O texto nos remete a psicologia da programação e descreve os 10 mandamentos da programação colaborativa, para que você não se prenda ao seu égo. Abaixo, segue a minha tradução/interpretação do artigo:

  1. Aceite que você irá cometer erros. A questão aqui é encontrá-los cedo, antes que estes sejam enviados para produção. Contudo, com exceção de alguns poucos programadores que desenvolvem sistemas para guiar mísseis na JPL, erros de programação raramente são fatais. Por isso nós, programadores, devemos rir e apreender com nossos erros.
  2. Você não é o seu código. Lembre-se que o objetivo da revisão de código é encontrar problemas, e pode ter certeza, que problemas serão encontrados. Não leve para o lado pessoal, quando um erro for apontado por alguém. Isso é normal, acredite.
  3. Não importa o quanto você sabe de “karate”, alguém sempre vai saber mais. Alguém sempre vai poder ensinar à você alguns “movimentos especiais” se você souber pedir e der o mínimo de espaço. Procure aceitar feedbacks dos outros, especialmente, quando você “tem certeza” que nenhum feedback é necessário.
  4. Não reescreva código sem consultar alguém. É tênue a linha entre “corrigir código” e “reescrever código”. Saiba a diferença e conseguirá realizar avanços na revisão e melhoria de código fonte.
  5. Trate as pessoas menos experientes com respeito e paciência. A maioria das pessoas não técnicas que trabalham com programadores geralmente tem a mesma opnião sobre nós: somos metidos, irritantes e egoístas. Não queira piorar ainda mais este estereótipo, tratando mal as pessoas que apenas querem apreender com você.
  6. A única constante nesse mundo é a mudança. Esteja aberto as mudanças e aceite-as com um sorriso. Veja cada mudança de requisitos, plataformas e ferramentas como um novo desafio e não como mais um problema que precisa ser combatido.
  7. A verdadeira autoridade nasce do conhecimento, não da posição ou cargo. Conhecimento é o que promove autoridade, e autoridade é o que gera respeito. Portanto, se você quiser ser respeitado, dessimine o conhecimento entre a sua equipe.
  8. Lute pelo que você acredita, mas aprenda a aceitar uma derrota. Aceite que muitas vezes suas melhores ideias não serão aceitas pelos outros. E mesmo que depois, você consiga prova que estava certo, não tenha pensamentos vingativos, nem faça comentários do tipo “Viu, eu te disse”. Muito menos faça a recusa de uma opnião sua, uma oportunidade para se tornar um mártir ou um inconformado que só reclama.
  9. Não se isole, mantenha contato. Não seja aquele cara incomunicável programando numa sala escura, que só é visto quando saí para comprar pizza ou coca-cola. Mantenha contato com as pessoas, fale com elas, apareça e esteja presente quando necessário. Num ambiente colaborativo, é fundamental que as outras pessoas saibam que podem contar com você.
  10. Faça críticas ao código fonte e não às pessoas. Seja gentil com o programador, não com o código. Sempre que possível, faça com que todos os seus comentários sejam positivos e direcionados para melhoria do código fonte. De feedbacks sobre padrões, especificações ou performance. Critique o que foi implementado, mas nunca, quem implementou.

10 mandamentos para controlar seu égo

Sinceramente, nunca havia encontrado algo que definisse tão acertadamente o comportamento humano na programação. Algumas pontos parecem clichês de tão óbvios, mas diariamente eu vejo problemas relacionados à eles. Particularmente, estou trabalhando exaustivamente nos itens 2 e 8 dessa lista a algum tempo, mas devo confessar, não é fácil. Reconhecer um erro, aceitar uma crítica e apreender com ela, é algo que vai se apreendendo com o passar dos anos.

O artigo está baseado no livro de  Gerald M. Weinberg: The Psychology of Computer Programming. O que mais me impressiona, é como um livro escrito em 1971 descreve com tamanha precisão os problemas que ainda enfrentamos hoje em dia. Sem dúvida, este merece estar entre as minhas “pendências” bibliográficas.

Por enquanto, toda manhã, ao sentar à frente de meu computador, repito em mantra:
“Eu não sou o meu código.. eu não sou o meu código… eu não sou o meu código… ”

Quanto menos, melhor

August 16th, 2008  |  Published in programação

Desenvolvimento de sistemas geralmente são repletos de discussões… longas e cansativas discussões relativas à arquitetura e design. Geralmente é no meio dessas discussões que se pode identificar um tipo peculiar de programador: o pattern-addicted developer.
Esse tipo de programador, geralmente tem um bom conhecimento técnico, domina a linguagem e os frameworks que estão sendo utilizados. Mas tem um vício perigoso: a necessidade insaciável em aplicar todos os design patterns que ele conhece em todos os projetos. Para ele, quanto mais classes e interfaces, melhor. Nas mãos de um pattern addicted, um cadastro simples pode ser tornar num monstrinho de n camadas, com milhares de Facades, Session Layers, DTO’s, VO’s, Factories, DAO’s, Adapters, Mediators e Business Delegates. Para o pattern-addicted, código fonte bem escrito, é complexo. Tão complexo, que poderá ser manutenido apenas por ele mesmo.

A simplicidade na programação, é um assunto que vem montivando muita gente. Rico Mariani (Microsoft), fala sobre simplicidade e performance:

I hardly think that one can make any conclusions about which vendor has the edge in performance from my article on Performance Tidbits.  If I was to summarize my advice in that blog in a few words it would be “don’t use OOP features that you don’t need.”

This is not to say that you should shun virtual functions, inheritance, or other features of modern programming languages.  Far from it, often they not only add clarity and maintainability they also improve performance.  But, as often, I find that people have written their code in some elaborate way when a much simpler model would have been equally servicable and more performant.  Whatever programming religion you may have I think you’ll agree that more complex language abstractions do not inherently help your design — rather each more sophisticated feature starts at a net negative and must somehow earn its way to positiveness with benefits such as clarity, ease of maintenance, performance, and so forth.
From Rico Mariani’s Performance Tidbits

Código fonte complexo, é um forte candidato a refactoring. Simplicidade é tudo. Não vamos utilizar design patterns sem necessidade. Faça a coisa mais simples possível que possa funcionar. Não pense em problemas que você ainda não tem. Se foque no que precisa ser feito agora. Torne o YAGNI uma filosifia de trabalho. O pessoal do 37signals, já falou muito a respeito disso:

Keep your code as simple as possible. You’d think that twice as much code would make your software only twice as complex. But actually, each time you increase the amount of code, your software grows exponentially more complicated. Each minor addition, each change, each interdependency, and each preference has a cascading effect. Keep adding code recklessly and, before you know it, you’ll have created the dreaded Big Ball of Mud.

  • Less software is easier to manage.
  • Less software reduces your codebase and that means
  • less maintenance busywork (and a happier staff).
  • Less software lowers your cost of change so you can adapt quickly. You can change your mind
  • Less software results in fewer bugs.
  • Less software means less support.

Não há nada de errado na aplicação dos design patterns catalogados pelo GoF – Design Patterns: Elements of Reusable Object-Oriented Software ou nos Blue Prints da SUN. Mas não crie problemas, apenas para poder utilizá-los.

Não vejo nenhuma vantagem em investir muito tempo tentando resolver algo, que um dia talvez, poderá vir a acontecer. Implementar soluções, na tentativa de resolver problemas que ainda não existem, não fazem muito sentido para mim. Todos os requisitos não precisam ser implementadas agora. Ao invés disso, acho mais inteligente fazer esforços para manter componentes desacoplados, permitindo que o sistema cresça interativamente de forma sustentável, à medida que novas funcionalidades vão sendo inseridas. As vezes, é fundamental saber o que deve se descartado.

The “secret” to good software design wasn’t in knowing what to put into the code; it was in knowing what to leave OUT! It was in recognizing where the hard-spots and soft-spots were, and knowing where to leave space/room rather than trying to cram in more design.
Brad Appleton

Em se tratando de software, quanto menos, melhor.