Archive for the ‘microsoft’ Category

Refletindo sobre Tendências

Friday, July 10th, 2009

Recentemente muita gente tem me procurado nos instant messengers da vida para perguntar sobre tendências. Existe uma idéia no Brasil de que quem está de for a “traz as novidades”. Isso podia ser verdade antes da Internet mas agora as coisas se espalham com tanta velocidade que em muitos aspectos o Brasil está muito na frente da Austrália.

Mas existe o outro lado que é o trabalho na ThoughtWorks. Os projetos que nós enfrentamos geralmente começam da mesma maneira que os que qualquer consultoria, de três letrinhas ou três pessoas, enfrenta. O diferencial que faz ser um lugar interessante para se trabalhar é o que acontece durante o projeto.

O que segue neste post é uma amarrado de impressões pessoais sobre os últimos doze meses, tanto sobre a Austrália quanto o que sei de outros escritórios. Se ele não for coeso ou fácil de ler eu peço desculpas mas encare como um braindump.

Os projetos para bancos e empresas do mercado financeiro em geral continuam bem parecidos. Em 2007 houve uma euforia em torno da bolha econômica e muitos projetos megalomaníacos –e, por conseqüência, extremamente interessantes do ponto de vista técnico- apareceram mas a crise os tirou do baralho nos tempos recentes. Os bancos estão gastando menos e buscando fazer mais dinheiro reutilizando a estrutura existente. A maioria dos projetos que eu tenho conhecimento dentro de bancos é para estender uma determinada oferta para novos clientes ou é para migrar de uma plataforma legada para algo menos dispendioso.

O interessante sobre o “legado dispendioso”, dentro e fora de bancos, é que muitas vezes ele se trata de coisinhas como WebSphere, Aqualogic, Biztalk, Tibco e produtos parecidos. Apos gastar rios de dinheiro implantando estes e não ver nenhum centavo de retorno real muitos dos grandes estão migrando para plataformas mais eficientes, quase sempre baseadas em software livre. Hoje em dia são comuns projetos de migração de Websphere para Jetty ou de BizTalk para serviços RESTful usando IIS, JSON e ASP.Net MVC, por exemplo.

Na parte de aplicações para Internet, onde geralmente eu me envolvo mais, as coisas também têm mudado bastante. Basicamente os projetos têm se dividido em startups e legado. As startups aparecem com um problema e algum montante de dinheiro. A plataforma mais utilizada para atender estes cenários é Ruby on Rails, geralmente fazendo deployment em algum serviço de Cloud Computing.

Cloud Computing é um tópico extremamente relevante tanto para ThoughtWorks quanto nos nossos clientes. Uma das coisas interessantes que fizemos no início do ano foi trabalhar junto com o Google no lançamento da AppEngine em Java (e outras linguagens).

As empresas com legado de Internet são sempre interessantes. Geralmente elas são algum grande prestador de serviço na área de mídia e possuem um ou mais websites antigos que têm aquela arquitetura manjada de rodar em um Weblogic ou Tomcat com um Apache de front-end. O problema é que hoje em dia o numero de usuários é muito superior e a velocidade com que funcionalidades têm que ser adicionadas e alteradas é muito maior. Após entender que os Googles e Facebooks da vida não usam Java EE e não pagam licença para a IBM as empresas estão desesperadas para atingir o mesmo nível de eficiência.

O que temos feito nesta área é utilizar a já citada Cloud Computing para realizar tarefas que não precisam ser executadas dentro do firewall (de crawling até rodar teste de carga), refatorar aplicações grandes para atingir escalabilidade horizontal e simplificar processos de deployment e gerenciamento de recursos.

Na área mais de programação em si as coisas não têm sido lá muito excitantes. As plataformas em específico não têm nenhuma novidade marcante mas a programação poliglota é uma realidade. Até hoje todos os projetos que tive alguma participação dentro da ThoughtWorks utilizavam mais de uma linguagem de programação (já descontando Bash e JavaScript).

Uma surpresa agradável foi a que tive no meu projeto atual, em que voltei a programar em .Net após 3 anos afastado. A maioria das coisas que eu realmente não gostava sobre C# e seu ecossistema foram removidos (exceto Windows e Visual Studio, duas peças que eu considero de qualidade inferior). A Microsoft continua enfiando frameworks e ferramentas terríveis pela guela dos seus clientes (MSBuild? TFS? WCF? WTF?!?) mas no geral as coisas estão bem melhores.

Em termos de livros sobre programação eu tenho me focado quase que exclusivamente nos conceitos presentes em linguagens e paradigmas de programação. Esta é a lista de livros relacionados que eu li desde que cheguei aqui:



Esta é a fila dos que faltam:


(fora os que ainda estão no meu carrinho de compras na Amazon. Livro na Austrália é ridiculamente caro)

Na parte de gerenciamento de projetos e metodologias as coisas estão engraçadas. Tem horas que a euforia anima, tem hora que dá náusea. Eu acho que o Bellware resumiu muito bem:

early agile adopters were looking for a way to do things better. later adopters are just trying to do agile, thus the failures

Eu vim para a ThoughtWorks para ver como é que quem introduz métodos ágeis há anos trabalha. Nos últimos meses eu trabalhei com pessoas que fazem isto há mais de dez anos e em empresas que adotaram agile antes de eu saber que ele existia. O que eu aprendi neste período inicial é exatamente o descrito acima: quando seu objetivo é ser ágil você falha, quando seu objetivo é sempre melhorar você tem chances de sucesso.

Todos os projetos que participei foram bem sucedidos? Depende de para quem você pergunta. Mesmo os clientes mais difíceis que tive acabaram ficando satisfeitos no final mas muitos projetos que participei (e o número de projetos é bem maior que o número de clientes) foram executados de uma maneira que o time não ficou satisfeito. Eu acho que neste caso é perspectiva. Como a maioria dos projetos são um fracasso colossal basta ter algum nível de sucesso que o projeto vira referência. O time, em compensação, tem um critério de sucesso muito mais alto e não considera o projeto como bem-sucedido.

É claro que no fim das contas o que vale mais é a opinião do cliente –tanto porque o problema dele foi solucionado bem como porque é ele quem paga a conta no final- mas eu já vi diversos problemas decorrentes deste tipo de coisa. De builds que começaram em 10 minutos e terminaram em duas horas de duração até um time que perde 50% do seu tempo corrigindo defeitos por falta de uma suíte de testes decente. Os problemas podem não ser grandes para aquele projeto em específico mas não prestar atenção há eles é mortal em médio prazo.

Minha conclusão é que a indústria está num estado melhor do que há alguns anos atrás. Tecnicamente estamos entrando em uma espécie de renascimento e isso promete render muito material para posts aqui. Em termos de gerencia de projetos e processos as pessoas estão finalmente se convencendo que tudo tem limite, até ineficiência.

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.

Adaptação de Linguagens

Thursday, October 18th, 2007

Mais um texto no philcalcado.com, desta vez algo mais genérico sobre modificações em linguagens. Eu ando lendo bastante sobre linguagens embutidas em outras (DSLs Internas) e outras formas de modificação de linguagem como Fluent Interfaces. É bem complicado chegar à qualquer conclusão em temas tão abstratos mas a experiência no uso destas técncias no dia-a-dia e no laboratório me mostraram que existem diferenças entre as formas de alterar uma linguagem. Em Language-Oriented Programming você cria linguagens, com Fluent Interfaces não.

Bom, mais sobre isso em Language Adaption.

.Net: Princípios OO e Alt.Net

Wednesday, October 10th, 2007

Duas rapidinhas sobre Microsoft .Net:

  1. Já está nas bancas a nova edição da Mundo .Net (#5) com mais um artigo meu na coluna sobre arquitetura. Desta vez o foco são princípios de Orientação a Objetos. O artigo é bem genérico eu recomendo que mesmo programadores de outras plataforma dêem uma olhada.
  2. Martin Fowler publicou uma ótima análise do que pode ser o movimento mais interessante dentro da plataforma .Net: o movimento alt.net.

Sistemas Simples, como Portais por exemplo

Sunday, October 7th, 2007

Esse debate no GUJ me mostrou umas coisas engraçadas. Eu já tinha idéia de como as pessoas não têm noção das dificuldades em manter um portal no ar, porque eu mesmo não sabia e porque entrevistei algumas dezenas de pessoas neste meu ano no setor, mas não deixa de ser engraçado.

Quando eu trabalhava numa pequena agência web, lá pelos idos de 2000-2002, eu atendi a muitos grande clientes. Petroleiras internacionais, bancos de investimento, bancos convencionais, fundos de pensão… para todos eu participei do desenvolvimento de sistemas web às vezes muito simples, ás vezes muito complexos. Existia um padrão neste segmento de sites institucionais feitos por pequenas agências, não sei se é assim hoje em dia mas era:

  1. Escolha um gerenciador de conteúdo (CMS)
  2. Escolha a tecnologia para construir o resto do site (se o CMS deixar)
  3. ‘Customize’ (yuck!) os templates (também conhecido como: Corrija os bugs do CMS)
  4. Entregue o site

Eu trabalhei com diversos CMS, na época todos os que prestavam eram pagos e caros. Para clientes pequenos usávamos o Publique!, para clientes maiorzinhos o Calandra, para clientes maiores o Vignette, para monstros que precisavam não de um portal mas de GED o Dcomentum e algumas vezes os caras pediam para trabalhar com Microsoft SharePoint. Minha opinião após algumas dezenas de projetos: Nenhum deles prestava (e duvido que prestem hoje).

Quando fui convidado para entrar para o mundo dos portais fiquei um pouco preocupado. Desde meus tempos na agência eu já havia trabalhado com sistemas de billing, telecom, logística, análise de risco e vários outros domínios complexos com sistema mega-complexos que de tão caros são cobrados em Euros e não dólares. Milhões de Euros, na verdade. Mas topei porque quem me fez a indicação é uma pessoa que sei que não me indicaria uma furada.

Veja só minha surpresa quando descobri que para um destes mega-portais de Internet um CMS não é opção. Ok, muitos deles até usam soluções dessas, meu empregador inclusive, mas apenas para uma parte muito pequena e repetitiva do trabalho. Para tudo que não puder ficar em cache o buraco é bem mais embaixo.

Mesmo para conteúdo cacheado, você acha que é simples manter uma página sendo acessada por milhões de pessoas num intervalo de tempo muito curto? Eu vejo quando uma pessoa na minha equipe evoluiu porque ela começa a ler sobre redes, gerenciamento de memória, etc. Outro dia um cara muito bom mas muito focado em Java que trabalha comigo recebeu uma reclamação de que a aplicação estava gerando um load muito alto nos servidores. Ele teve que se virar para entender o que é o load de um servidor e porque o CPU não fica em 100% mesmo quando o load atinge duas casa decimais. Daí a coisa evoluiu para entrar no servidor e ficar tirando thread dumps (que muitos nem sabem o que é) para analisar o sistema, depois olhar o fonte do java.util.HashMap e identificar um problema de loop infinito que acontecia nesta classe somente quando havia uma grande concorrência. É engraçado, o cara entra com aquela mentalidade de ‘analista/desenvolvedor JEE’ e sai como um profissional de verdade. Eu acho que todo mundo devia trabalhar num lugar assim, ou fazer estágio ao menos.

E aí as pessoas dizem que os nove sites citados lá pelo estudo são simplezinhos e por isso usam LAMP. Isso é muito protecionismo, meu Zahl…

Java é uma boa plataforma para vários casos, mas não para todos. O modelo de IPC pobre, o deployment caixa-preta e a falta de uma meta-programação de verdade afetam fortemente a plataforma mas não é nada que não se consiga viver com. O ponto é que as outras plataformas possuem também suas diversas vantagens em vários casos, entre eles sites como os citados. Cada vez mais os portais possuem maior lógica na Camada (Tier) de apresentação. Os sistemas que temos desenvolvido no meu dia-a-dia de portal geralmente são compostos por um site que possui lógica de aplicação e acessa vários serviços.

A lógica de aplicação eu sinceramente mudaria para Rails sem pensar meia vez. O único ponto que me faria ponderar a princípio seria performance, ironicamente Java é hoje uma das mais performáticas plataformas disponíveis, mas mesmo hoje performance é garantida através de outros meios como caches e hardware (nota: existem poucas coisas que deixam um sistema tão lento quanto construí-lo usando um CMS).

A parte de trás da aplicação, onde ficam os serviços, não seria tão simples. Alguns serviços podem ser migrados para plataformas leves sem pensar duas vezes (muitos deles já estão em PERL e PHP, na verdade) mas assim como faz o Flickr eu usaria Java em alguns deles (o flickr é em PHP e usa Java para upload).

O ponto não é usar ou não Java. O ponto não é Ruby on Rails ganhar de Java no caso XYZ. O ponto é usar ferramentas certas nos lugares certos. Devia fazer parte da ética profissional este tipo de coisa…

Arquitetura na Mundo.Net

Sunday, August 5th, 2007

Deve estar nas bancas esta semana a edição atual da Mundo .Net. Esta é a primeira edição com minha participação na coluna sobre arquitetura de sistemas. Existe um estereótipo generalizado de que o Mundo .Net (sem trocadilhos) é muito pouco preocupado com arquitetura de sistemas, consumindo sem pensar as ferramentas que a Microsoft disponibiliza.

Apesar do exagero desta afirmação há de se convir que a maioria dos projetos em .Net usa ‘arquitetura de caixinha’, mas a diferença real para a comunidade Java, por exemplo, é que Java possui muitas arquiteturas de caixinhas para se escolher. Minha idéia para a coluna é focar em temas sobre arquitetura de software que podem ser utilizados nos dois mundos, que são parecidos em muitos aspectos.

Nesta edição o foco é Domain-Driven Design. Eu já falei sobre este tema em uma edição passada da Mundo Java mas desta vez o foco não é nos padrões e sim na modelagem de domínio, com exemplos.

Construindo Expressividade com Linguagens Elegantes

Friday, July 27th, 2007

Ainda não vi uma definição sobre o que seria uma linguagem elegante, então lá vai a minha:

Uma linguagem elegante é baseada em primitivas simples e extensíveis e, principalmente, sem muitas exceções.

Segundo esta definição Ruby, Smalltalk e LISP são elegantes. Java é um pouco, C# com suas centenas de exceções (sobrecarregar + é diferente de sobrecarregar [], dentre outras várias exceções) não é.

Uma linguagem elegante é simples e compacta. É de se esperar que não tenha sobrecarga de operadores, mas isso não é verdade. O problema das pessoas com sobrecarga de operadores é porque elas vêem isso como uma quebra da rule of least surprise. Essa regra diz (implora, eu diria) para não surpreendermos nossos usuários modificando o mundo que eles já conhecem para que uma ação traga consequências não esperadas. Por exemplo imagine que você vai modificar um programa como o ls para dar mais performance (uau, você é bom!). Faça o que quiser mas não mude os parâmetros de entrada e saída ou você vai quebrar um zilhão de programas e scripts pelo mundo todo. Caso introduza uma feature nova faça o usuário explicitamente solicitar por ela (passando um flag no estilo ls -lira –my-fancy-new-feature) e mantenha o default como o antigo.

E onde entra sobrecarga de operadores nisso? Lá no seu primeiro curso de programação (ou no seu primeiro livro se você opta pelo caminho mais difícil) deve ter aprendido sobre literais, variáveis, condicionais e… operadores. Operadores são caracteres especiais com uma função bem definida na linguagem, por exemplo o operador de divisão, de resto, de adição…

Em Java, quando você chama:

String texto = "abc".toUpperCase();

É fundamentalmente diferente de quando chama:


int numero = 12 + 24;

Porque um método e um operador são coisas diferentes e você aprendeu a pensar desta forma. Se amanhã eu puder sobrescrever o operador + para que escreva algo na tela você vai se surpreender porque não era isso que o manual da linguagem te disse.

Ainda assim, existem muitas ocasiões onde sobrecarga de operador são mais que convenientes, são semânticos. Imagine o exemplo do nosso BigDecimal:


BigDecimal a = new BigDecimal("100");
BigDecimal b = new BigDecimal("300");

Some os dois. Ok, você é um programador Java esperto e sabe que vai ter que fazer algo como:


BigDecimal resultado = a.add(b);

Mas disso até me dizer que é melhor que usar ‘+’ é outra história.

Mas e a simplicidade? Não é legal termos um conjunto pequeno de operadores que faz coisas previsíveis e que servem na maioria das vezes? Sim, é! Mas num mundo onde tudo migra para mais expressividade, com Model-Driven Development e Domain-Specific Languages ter este tipo de limitação não é interessante. As melhores linguagens para construir DSLs são as mais flexíveis e por acaso as mais elegantes, que coincidência, não? E como Ruby, que se enquadra nestes dois aspectos, lida com isso?

Simples. Em Ruby não existem operadores, pelo menos não como você está acostumado em Java, operadores são apenas apelidos para métodos. A vantagem disso é que se muda o modelo mental, a partir do momento que você sabe que um operador e um método são a mesma coisa você tem com operadores o mesmo cuidado que tem com métodos. Ao chamar add() do BigDecimal você tem que saber se o método vai retornar o resultado como um objeto separado, se vai modificar os objetos passados como parâmetros, etc. Como você faz isso? Lendo a documentação até se familiarizar com a classe e seu idioma. Após familiarizado você começa a usar sem pensar.

E quando você espera estar lidando com uma classe que sobrescreve um operador e na verdade recebe como parâmetro uma subclasse dela? Sem problemas! Se o autor seguiu os princípios básicos da Orientação a Objetos, que derivam do Design by Contract e o Princípio de Substituição de Liskov a subclasse tem que obedecer o contrato da classe-pai, e se você obedeceu os mesmos princípios não precisa de nada que não esteja no contrato.

Esse tipo de resistência com funcionalidades é o tipo de coisa que se elimina aprendendo várias linguagens e estudando suas motivações. Existem algumas linguagens como as citadas que merecem ser estudas ainda que você nunca as vá utilizar de fato. Elas abrem a sua cabeça.

Model-Driven Development é Durepoxi

Friday, July 27th, 2007

O Paulo Vasconsellos lá do finito ensaiou sua opinião sobre como código não pode representar a documentação sobre um processo de negócios. O post que originou a conversa é bem fraquinho, mas o ponto é bom.

Basicamente a idéia é que não dá para confiar no código porque ele possui o que Joel Spolsky catalogou como ‘leaks de abstração’ em um dos seus artigos mais citados. ~Tenho que admitir que isso pode ser verdade na maioria dos casos mas apenas porque as pessoas ainda não aprenderam o conceito simples de separação de responsabilidades, e isso é muito pior na cultura .Net que é a do autor do artigo original.

Imagina que temos um processo de negócio automatizado num software OO. A coisa é simples, o clássico e onipresente exemplo de adicionar usuários a um grupo:


void adicionarUsuario(Usuario u, Grupo g){
g.adiciona(u);
}

E como estamos falando de um software OO as regras de negócio estão nos respectivos objetos (grupo e usuario) e não nesse método de serviço. Muito bem, eu consigo gerar uma documentação em fluxograma, UML, o que for desta sequência simples de instruções imperativas. O problema é que software não é simples assim.

Eventualmente nós precisaremos persistir a alteração feita no banco de dados.


void adicionarUsuario(Usuario u, Grupo g){
g.adiciona(u);
repositoriousuarios.atualizar(u);
}

E possivelmente precisamos saber se o usuário logado possui direito a fazer esta alteração, esse é um requisito não-funcional de segurança. Adicionar um log também é útil para auditoria.


void adicionarUsuario(Usuario modificador, Usuario modificado, Grupo g){
if(podeAlteraroutrosUsuarios(modificador){
g.adiciona(modificado);
repositoriousuarios.atualizar(modificado);
logger.info("Alterou");
}
else{
throw new IllegalQualquerCoisaException();
logger.error("Tentou alterar");
}
}

E isso pode piorar ainda mais. Agora utilize o código acima como documentação de negócios por favor. Mostre ao seu cliente e peça para ele tentar te explicar. não dá, né? E por quê? Porque cada uma destas coisas são conceitos ortogonais, que deviam ser implementados por técnicas de AOP e não embolados no meio do código de negócio.

Domain Driven Design possui a modelagem de negócios no código como sua essência. Um dos pontos que mais causam dúvidas, por exemplo, é o da diferença entre Repositórios eDataMappers (DAOs no mundo Java EE). A diferença é que eu coloco um repositório num diagrama de negócios (ainda que chame de outra coisa) mas não coloco um DataMapper . E por quê? Porque a responsabilidade de um Repositório é referente à objetos que mapeiam o negócio enquanto a responsabilidade de umDataMapper é transformar objetos em tabelas (ou coisa do gênero) e objetos ou tabelas não são conceitos de negócio. Assim ainda que um DataMapper implemente um Repositório eles são tratados sob pontos de vista bem diferentes para análise de sistemas.

No passado nós tínhamos uma discrepância enorme entre os modelos de negócio e o modelo físico do software. Há mais de vinte anos que não há motivo para esta diferença existir, exceto uma cultura dominante. O problema, como sempre, está nas pessoas.

Model-Driven Development, conjunto de idéias que Domain-Driven Design faz parte, é exatamente sobre isso. Por enquanto nós ainda precisamos educar os desenvolvedores para que usem as ferramentas de maneira correta, num futuro próximo eu espero que Domain Specific Languages poupem este trabalho na maioria dos casos.

Sobre Hackers e Talkers

Tuesday, July 3rd, 2007

É impressionante o que se consegue com um time de qualidade. Independente de qualquer ponto que qualquer um (inclusive este que vos escreve) tenha contra o Mono,a implementação livre do Microsoft .Net Framework, o time do conturbado Miguel de Icaza mostrou uma excelente performance ao implementar em dias uma especificação nada simples.

Utilizar um time composto por hackers minuciosamente selecionados é algo inviável no mercado comum -simplesmente não existem profissionais suficientes e geralmente temos um hacker cercado por um oceano de Morts- o que faz este acontecido ainda mais louvável.

Cuidado com Domain-Driven Design

Friday, June 22nd, 2007

Em tecnologia existe um fenômeno interessante. Existe um problema qualquer. Alguém resolve o problema de um modo e as pessoas começam a usar este modo. O detalhe é que as pessoas não param para ler as fundamentações técnicas, a coisa vira um grande grupo de achismo. Aí surge outra solução que é mais eficiente e utilizada por uns poucos que tentam convencer os outros. Quando finalmente as pessoas se convencem elas repetem o ciclo, não estudando a fundo as bases e caindo no conto do vigário.

Este post no GUJ mostra um claro desvio dos padrões estipulados por Domain-Driven Design. Vamos desmistificar a coisa: DDD é uma forma disciplinada de criar um Domain Model, só isso. O foco da técnica é criar um domínio que “fale a língua” do usuário. Isso não quer dizer que você vá “mapear o mundo real” com objetos, esse não é o objetivo nem da técnica nem de Orientação a Objetos em primeiro lugar.

Passeando pela thread, você pode perceber diversas coisas fora do que é definido em DDD. Os conceitos de Domínio e Contexto confusos. Domínio é o que o programa (seja um exercício de faculdade ou um sistema empresarial) modela, o que ele se propõe a resolver. O modelo que você criou deste domínio (o Domain Model) certamente possui intersecções com modelos criados em outros sistemas, serviços, etc. Neste caso o dividimos em Contextos:

Explicitly define the context within which a model applies. Explicitly set boundaries in terms of team organization, usage within specific parts of the application, and physical manifestations such as code bases and database schemas. Keep the model strictly consistent within these bounds, but don’t be distracted or confused by issues outside.

A analogia do círculo é péssima porque ela foca em uma caixa-preta, que não é um Módulo em Domain-Driven Design. Em DDD um módulo é quase que exatamente como um pacote em Java ou namespace em C#. O Contexto é dividido em Módulos, que agrupam entidades com conceitos em comum. A comunicação entre Contextos e entre Módulos é dada através de diversos padrões e técnicas.

Existe uma confusão também com Value Object. Em DDD um Value Object é um conceito de domínio como qualquer Entidade a diferença é que ele não tem identidade própria. Se eu pegar uma nota de dez reais emprestado de você você não exige que eu te devolva a mesma nota, apenas que devolva uma nota de mesmo valor ou equivalente. Este conceito do “mesmo valor” é o coração do Pattern. O tópico coloca o pobre VO como um TO, mero agrupamento de dados.

A parte da transação também é muito complicada. Desde o início deste século que nós estamos separando estas responsabilidades (autenticação, transações, log, etc.) como conceitos ortogonais. Conceitos ortogonais não devem, quando a tecnologia permite, estar implementados junto com regras de negócio, junto com entidades de domínio. Para isso suamos a AOP expressa por ferramentas como Spring Framework ou EJB (seja 2.1 ou 3.0). Eric Evans fala sobre separação entre domínio e tecnologia:

The domain model is a set of concepts. The “domain layer” is the manifestation of that model and all directly related design elements. The design and implementation of business logic constitute the domain layer. In a MODEL-DRIVEN DESIGN, the software constructs of the domain layer mirror the model concepts.

It is not practical to achieve that correspondence when the domain logic is mixed with other concerns of the program. Isolating the domain implementation is a prerequisite for domain-driven design.

Falar que ActiveRecord não funciona é negar a realidade. Frameworks como Ruby on Rails, Castle e Grails se baseiam nele, não é porque não até até então nenhuma proposta Java de framework que o conceito não funciona. O exemplo dado não representa qualquer problema, já que transações são tratadas em um conceito ortogonal separado, como descrito acima. Se AR se aplica bem ou mal no caso X ou Y, com DDD ou o que for é outro assunto, que aliás já tratamos aqui mais de uma vez.

Interessante que toda a thread teria começado porque o autor original achou que os artigos deste blog não são completos o suficiente. Independente de serem (e não são) ou não, o que eu sempre recomendo éleia a bibliografia. Infelizmente tem (muita) gente que prefere simplesmente ter um pseudo-resumo rápido num fórum. Fazendo uma análise dos pontos que levantei aqui e de outros no texto em questão eu percebo que o autor original em si não teve muito sucesso em aprender os conceitos de Domain-Driven Design porque procurou o meio errado. Outro dia uma thread no mesmo fórum sobre o mesmo tema corria parecido, com uma pessoa fazendo críticas em cima de um modelo usando Repositórios. O problema é que o cidadão em questão nem sequer leu sobre a técnica antes de criticar, nem mesmo no resumo disponível gratuitamente apenas pedia um exemplo como se quatro linhas de código fossem passar 500 páginas de conhecimento. O mundo tem pressa e preguiça, mas até onde isso leva?