Archive for the ‘ruby’ Category

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…

Ruby “ou” Rails?

Tuesday, October 2nd, 2007

Esse post no GUJ me fez pensar sobre a melhor maneira de absorver algo como o Rails. Rails é uma plataforma de desenvolvimento altamente produtiva e boa parte da produtividade vem do fato de que não é preciso abstrair um domínio na linguagem.

Desenvolvimento de aplicações web é um domínio que inclui diversos conceitos e abstrações. Vejam por exemplo uma sessão web. Se uma pessoa ler sobre o protocolo HTTP em si vai perceber que não existem sessões, o protocolo não mantém estado entre as requisições. Para burlar este problema nós utilizamos cookies ou URIs especiais para informar ao servidor o ID da sessão do cliente. Este é um conceito.

Em Java (ou outra plataforma parecida) vamos abstrair a sessão em uma classe. É desta forma que trabalhamos em Java: criamos classes para representar os conceitos do domínio.

O problema é que até conhecer o suficiente para utilizar de maneira adequada esta abstração na forma de classe você precisa conhecer o que é uma classe e todos os conceitos derivados desta. Basicamente não se consegue criar algo razoável sem saber um mínimo de programação orientada a objetos.

E como Rails resolve isso? Rails abstrai boa parte destes conceitos na linguagem. Ruby é uma linguagem OO e é possível representar a sessão da mesma maneira que se faz em Java mas este não é o meio utilizado em Rails e esta forma de representar as coisas é seu maior diferencial.

Uma sessão em Rails está embutida implicitamente dentro do controlador. Trabalhar com elas é muito simples, para efeito de comapração é como se seu controlador em Java herdasse uma classe que possuísse o objeto que representa a session (que tem a mesma interface que um Map) como atributo protected. Exceto que o acoplamento gerado para acessar a session da classe-mãe em Ruby é muito fraco enquanto em Java seria enorme (na verdade provavelmente a melhor opção em Java seria um método e não um atributo. Em Ruby estes conceitos são bem mais flexíveis) é mais uma questão de filosofia do framework do que de linguagem utilizada em si.

Apesar da polêmica se é ou não uma Domain-Specific Language, Rails é um exemplo claro de Language-Oriented Programming. Neste paradigma de programação (praticado em Lisp desde…sempre!) a linguagem utilizada é modificada e estendida para acomodar os conceitos do domínio. No caso do Rails a linguagem Ruby ganha características que permitem ser estupidamente simples criar uma aplicação web.

E o que isso representa para quem está aprendendo? Eu diria que existem 2 tipos de pessoas que desenvolvem em Rails: desenvolvedores e desenvolvedores de aplicações web. Qual a diferença?

Desenvolvedores aos quais me refiro são desenvolvedores profissionais de software (analistas, programadores, hackers, o que quer que você queira chamar). São pessoas que se dedicam profissionalmente a entender as milhões de coisas que são importantes no desenvolvimento de projetos de software. Utilizar Rails para eles é apenas se beneficiar de uma boa ferramenta que implementa conceitos de MVC, ActiveRecord, LOP, Domain Model, Meta-Programação, convention over configuration, JavaScript, etc.

Para eles eu recomendo primeiro aprender Ruby. Rails sem Ruby é exotérico demais, você não vai entender como é possível que sua classe ganhe métodos conforme precisa deles e outras coisas estranhas (principalmente se você vem de Java ou C#).

O outro estereótipo, o desenvolvedor de aplicações web, geralmente é umc ara com menos conhecimento técnico, menos interesse em construção de software e habilidades em outras áreas. Pode ser o designer que quer fazer seus projetos com relativa independência de programadores, pode ser o cara que tem um estalo e uma brilhante idéia para uma aplicação Web 2.0 que o fará milionário… O ponto é que desenvolver software para este cara é só uma parte do processo, o meio, e não o fim. Este cara não precisa aprender tantos conceitos, ele pode se basear em receitas prontas e correr para um técnico quando precisar de algo mais heavy-metal. Para este cara eu recomendo aprender diretamente Rails, eventualmente ele pode melhorar Ruby e programação em geral com a evolução do seu projeto.

Interessante notar o conceito que funciona com Rails e com desenvolvimento baseado em Domain-Specific Languages (sendo Rails uma ou não): o usuário não vai desenvolver o software sozinho. Ele se baseia em algo construído para ele por um técnico (seja o framework Rails ou uma DSL) mas não consegue sair muito daquele escopo específico e limitado sem acompanhamento profissional. Este é o objetivo dos pesquisadores de DSLs neste momento.

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.

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?

Microsoft: RIP?

Monday, June 4th, 2007

Paul Graham e Martin Fowler decretaram o fim da MSFT. Não é a primeira vez que isso acontece mas desta vez são grandes nomes, um sempre escandaloso e um geralmente bem imparcial, na ordem. Como falamos aqui nos últimos meses, Redmond tem surpreendido a comunidade de desenvolvimento (como nota Fowler) com novidades realmente interessantes mas… Microso$oft é MSFT, não tem jeito. Após tantos anos jogando com as peças erradas vão ser necessários muitos milhões de dólares e neurônios para virar a mesa, e por mais que dólares não faltem neurônios ainda são muito caros para Redmond, já que seu preço varia com o freguês.

Enquanto Graham se atêm às perdas de mercado na computação de desktops Fowler fala sobre a perda de mercado da plataforma .Net. Vai ser necessária muita inovação, tanto em SO quanto em plataforma de desenvolvimento, para reverter o jogo. Em Plataforma temos visto aqui que realmente eles estão tentando, e muitas vezes conseguindo. A parte de SO é a antítese: cópias de recursos com mais de dez anos de existência.

Dado que a MSFT prende sua plataforma ao seu SO, o sucesso ou fracasso de um influencia o outro. Este risco sempre esteve presente para o programador .Net mas antes ele era tão irreal que era simplesmente desconsiderado. Agora ele está aí nas mãos dos milhares de MacBooks nas mãos de quem mora em países civilizados (do tipo que não faz um MacBook custar R$6.500,00) e dos sabores de GNU/Linux que alimentam os datacenters. Na lista do Graham sobre como salvar a MSFT eu incluiria abrir sua plataforma para externos. Por mais que o Windows continue caindo pelo menos uma parte da empresa estará a salvo.

A Culpa é da Marvada

Tuesday, May 22nd, 2007

O Vitor respondeu meu post, eu tentei colocar um comentário mas ficou muito grande, então vamos tentar retrucar por aqui mesmo :)

Eu entendi que ele quis dizer algo como “em >coloque -um-valor-muito-alto-aqui<% dos casos usar OO é overhead” e, como disse, concordo em parte, mas acho que mais uma vez houve uma certa ênfase errada.

Para começar, acho que mudou bastante de idéia. Em Fevereiro você disse:

Como um bom amante da Orientação a Objetos pura eu odeio os bancos de dados tradicionais e acho os frameworks de O/R um saco (além de ser uma grande gambiarra)! Por isso eu uso Prevayler. :D

Que foi o que começou este debate todo. Bom, vamos lá.

Por exemplo, com o BabaXP eu forcei a implementação de um DAO, mesmo usando o Prevayler. Achei que era possível criar um DAO OO, algo bonito, que abstraísse as diferenças entre Prevayler e um banco relacional qualquer. Me enganei. É impossível fazer algo nesse nível só por causa de uma única diferença entre as duas tecnologias, o acesso direto a memória dos dados.

Bom, Prevayler em si não é OO, como já discutimos no seu blog e em um post passado aqui neste mesmo, mas ainda que fosse não há problema em ter um Mapper (que é conceito por trás de um DAO) entre dois domínios de objetos diferentes. Na verdade, Eric Evans possui ótimos textos sobre Context Mappers no seu livro que fazem exatamente isso.

Quando trabalhei com Hibernate 2 e EJB 2, não consegui imaginar uma forma melhor de se programar do que seguir um fluxo de ida e volta: Locator -> Facade Session Bean -> Transaction -> DAO -> Hibernate Entity. Com VOs circulando entre eles. Aparentemente uma bela estrutura OO, exceto por um problema: os algoritmos continuavam seqüenciais, apenas em objetos diferentes. Os objetos não resolviam os problemas da regra de negócio, mas sim simplificavam o uso da própria tecnologia (EJB). Não haviam objetos inteligentes, apenas os JavaBeans secos, como o Hibernate 2 queria, e VOs secos, com regra de negócio pertinente ao objeto e só.

Ahm? Por que o Hibernate fazia você usar DTOs? Eu usei Hibernate com objetos de negócio nesta versão e não tive nenhum problema, poderia explicar melhor? Mesmo os tão mal-falados EJBs podem ser utilizados com objetos. Não não é tão fácil quanto em JPA/Hibernate 3, mas também não é difícil.

E não, DTOs/VOs/TOs ou como estejamos chamando esta semana não fazem um bom modelo OO, muito pelo contrário.

Uma estrutura semelhante foi criada com o JavaFreeCMS, uma arquitetura Action Based não poderia gerar outro resultado do que uma implementação Action Based, que é um nome mais bonito para implementação seqüencial. Por mais que eu quisesse implementar algo OO, tinha algo que me prendia ao modelo relacional. Cultura? É, foi sim. O JavaFreeCMS foi baseado no phpNuke, no qual é muito fácil adicionar módulos e componentes. Lá basta você adicionar um .php e criar a tabela, pronto. Tentei fazer algo semelhante, mas orientado a objetos. Acabei descobrindo que o esforço para implementar tal flexibilidade era tamanha que eu precisaria de uma equipe para desenvolver um Simples e Idiota CMS OO. Acabei chutando o balde e implementando o mais simples possível.

Foi então que comecei a suspeitar da utilidade da Orientação a Objetos e dos Design Patterns. Como falei antes, até então eu considerava que o problema era eu. Que eu era incapaz de fazer algo bom utilizando o melhor da OO e dos design patterns. Afinal, tanta gente mais experiente falava bem dos patterns e tals, alguma utilidade eles deveriam ter, não é? No entanto, hoje eu vejo que não é bem assim.

Antes de mais anda não existe nenhum vínculo entre OO e Design Patterns, um existe sem o outro. Depois, existem diversos CMS OO por aí para provar que não é bem o paradigma que tem problemas. Em boa parte deles adicionar ou remover módulos é simples, provavelmente o design que se fez para este caso do JavaFreeCMS em específico não foi adequado (aliás o Prevayler prega um paradigma Action-based em suas transações).

Não adianta você querer implementar a sua estrutura de dados com o melhor da orientação a objetos se você vai acabar migrando esses dados para um sistema relacional. Você tem um esforço considerável para identificar várias heranças, composições, agregações, relacionamentos uni e bi-direcionais e após isso mais um esforço para migrar essa estrutura para o ambiente relacional. Para variar, não existe nenhum framework de O/R que consiga mapear atributos específicos de cada abordagem sem perder em performance, em simplicidade ou produtividade. Até hoje eu nunca vi ninguém conseguir implementar um sistema completo OO e somente depois de tudo criado integrar com alguma forma de persistência de maneira transparente. A OO aplicada, com todos os seus recursos e ideologias, neste tipo de aplicação, só serve para complicar as coisas, trazer mais trabalho e problemas para o desenvolvimento.

Você está ignorando simplesmente décadas de técnicas de mapeamento Objeto-Relacional e, mais uma vez colocando problemas no Hibernate e JPA que eles não possuem. Pode explicar por que eles não fazem este mapeamento?

Segundo este conceito podemos chegar à conclusão que linguagens de Assembly foram uma coisa muito ruim, já que elas apenas adicionam uma abstração em cima do modelo “real”, de linguagem de máquina. Será que elas não trazem benefícios?

A mesma coisa pode-se dizer das aplicações request-response, que mudam de nome a cada ano, mas continuam a mesma coisa. Muitos frameworks não nos deixam fazer muita coisa da OO. Você recebe uma lista de parâmetros e devolve uma lista de resultado. Lista == tabela == relacional. Para provar, pense no seguinte, a cada resposta que um sistema como esse dá, ele carrega todos os relacionamentos de cada objeto, ou carrega apenas a parte que interessa ou que a aplicação cliente usaria? Agora outra pergunta, para isso utiliza-se VOs específicos para cada request ou um único VO com sistema de lazy loading? Implementar um VO para cada requisição é dose. Deixar por conta de um lazy loading também muitas vezes falha (ou a conexão fica aberta e bloqueia outros acessos ao banco ou ela se fecha e se o usuário pedir algum objeto, irá ter um belo “session closed”). Alguém já ouviu falar no conceito de “páginas” com Orientação a Objeto? Não né. Por que esse conceito foi criado pelos bancos de dados e implementado graciosamente com a instrução “limit” no SQL.

Acho que você confundiu um pouquinho listas de estruturas de dados com álgebra relacional. Em um programa eu posso ter listas de qualquer coisa, e elas não precisam obedecer aos princípios de álgebra relacional. Por um acaso bancos hierárquicos ou em rede não implementam listas? Por um acaso uma HashTable é relacional? Prevayler trabalha com listas de objetos, ele é relacional então, certo? Sua prova… bem, não condiz com a realidade.

2007. Faz pelo menos 3 anos que VOs são completamente desnecessários em java, se é que algum dia foram. Lazy loading funciona muito bem, obrigado. O problema de sessão aberta é contornável facilmente com algumas técnicas, apesar de sim, ser um problema real, mas nada impede que eu tenha paginação em uma consulta OO via Hibernate, basta eu fazer eager fetching (que pode, inclusive, contar com consultas polimórficas) antes.

Mas… putz…dizer que páginas foram criadas nos bancos de dados é ignorar solenemente os diversos usos de paginação em memória e outras estruturas uhm… não relacionais.

Pense na seguinte frase: Os dados saem de uma base relacional, são transformados em objetos, executam uma regra de negócio simples (Somas, médias, grupos, contatores, etc), são transformados em relacional novamente e exibidos. Esse é o fluxo de muitas aplicações web e desktop. Se é assim, para que diabos alguém adicionaria aquela transformação e destransformação para OO no meio do processo?
Não parece. É, uma coisa desnecessária. Se a regra é simples, se a arquitetura que você utiliza dificulta o processo ou se os objetivos da aplicação são “relacionais”, para que ficar inventando moda? Os Design Patterns também não escapam. Em várias ocasiões eu vi que era possível implementar padrões um pouco mais complexos diretamente na regra de negócio, como o State por exemplo. No entanto, o State é tão complexo e chato de manter que não vale apena trocar por um campo de “situação” e mantê-lo com o próprio objeto.

Sua aplicação é simples? Ótimo! Pode abrir mão do bom uso de OO e ainda assim manter uma estrutura legível e com manutenção razoável? Excelente! Só não tome isso como regra geral. Se você acredita que a complexidade de criar um programa com estruturas de dados de objetos quase nunca é justificável eu realmente não entendo o que te faz não utilizar uma linguagem que permita este design e ainda traga mais vantagens, como ASP clássico, ColdFusion, PERL+CGI ou PHP. Java pra quê?

Quanto á confusão com Patterns vou considerar respondida acima.

Obviamente, nem toda a aplicação web é tão simples assim, mas minha intuição me diz que 98% do mercado brasileiro segue essa estrutura. Apenas 2% das aplicações merecem ter boas implementações de OO e Design Patterns.

Mais ou menos concordo (mais sobre isso abaixo), mas existe um problema intrínseco aí. Como você frequentou a academia mais tempo acredito que saiba melhor que eu que existe algo chamado programação estruturada e suas variantes, dentre elas programação OO e procedural. Agora, dado que a grande bibliografia de Yourdon, Page-Jones e seus amigos mostra que fazer programas em paradigma procedural exige várias técnicas (fan-in, fan-out, coesão, divisão de módulos, controle de flags, acoplamento… lembra?) para manter um programa… hmm… editável… acho que você está saindo da programação estruturada pura e simplesmente, certo? Segundo este princípio crie classes apenas com atributos públicos sendo manipulados por funções estáticas, aliás, por UMA GRANDE função estática :P

Eu concordo em gênero, número e grau que OO pode ser um overhead tremendo quando se tem um domínio simples, e inclusive defendo arduamente o uso de DSLs simplificadas para construção de sistemas, mas simplesmente largar o paradigma OO em favor de algo que não é OO nem Procedural é retroceder para antes de Dijkstra. Só falta um GOTO.

Entre esses 2% estão, em geral, aplicações com baixa quantidade de informação do usuário: compiladores, ferramentas de BI, diagramadores de interface, toolkits gráficos, aplicações como diagramadores vetoriais, gimp, blender, engines de jogos, browsers, IDEs, etc. Aquelas aplicações de sistemas de informação que seguem a estrutura de frameworks, o estilo de linguagens ou APIs, definitivamente não precisam de mais padrões ou mais OO. Você está preso a ela, portanto faça o que ela mandar e você será produtivo, invente moda e já era! Tente trabalhar de uma forma diferente da MVC com o Swing, e você se verá enrascado. Tente transformar as entities do EJB em Business Objects e estarás f.u.d.i.d.o. :)

Sei não. Ou minha realidade é muito diferente ou a sua é meio..exótica. Nos últimos anos trabalhei em sistemas de gestão de previdência privada, billing de telefonia, análise de risco, gestão de malha ferroviária, gestão de passageiros, conteúdo multimídia, gerenciadores de conteúdo (sim! e alguns deles)… e boa parte das pessoas que eu conheço ficam com sistemas parecidos. Todos eles tinham lógica a modelar como objetos

Fiz também muito destes CRUDs simples na vida mas eles definitivamente não são 98% nem do que eu fiz nem do que as pessoas que conheço fizeram. Se alguém só faz CRUDzinhos simples que nem um Domain Model se justifica a primeira sugestão é deixar Java de lado e trabalhar com algo mais produtivo como PHP4. O problema é que sistemas crescem, se integram e mudam, e acho que é este ponto que você ainda não entendeu que um bom design, seja ele OO ou não, faz diferença.

Caindo nos bons designs você irá ver um bom design procedural e perceber que existem práticas que são melhor implementadas num modelo de objetos, como quando você precisa proteger uma estrutura de dados de acesso indevido, ou sua invariante. Foi assim que o design de aplicações evoluiu até hoje.

Concluindo, nos dias de hoje, em grande parte dos sistemas de informação, a estrutura relacional atuando sozinha é perfeita! Ninguém precisa de Objetos para tais atividades, a não ser, é claro, que você utilize um banco de dados Orientado a Objeto, aí a coisa muda de figura. Mas como muita gente tem medo deste recurso… Hoje, está bem claro para mim: Aplicações com mais regra de negócio do que informação, utiliza-se orientação a objetos. Para sistemas de informação, onde há mais dados do que regras, vai do banco. Bancos relacionais, aplicações relacionais, SQLs e etc. Com bancos OO, aplicações OO.

Isso é complicado. Se você coloca o banco de dados no centro do universo é bom colocar as regras de negócio lá também, cheia de Stored Procedures, e ficar apenas com front-ends em linguagens de programação convencionais. Do contrário o que você faz quando duas aplicações tentam compartilhar o mesmo conceito? Se eu tenho um conceito formado por um join entre duas tabelas o conhecimento sobre este formato deve ser espalhado por todas as aplicações que utilizam o conceito, e quando eu mudar a implementação das tabelas tenho que mudar TODOS os sistemas, ou criar malditas views para segurar o legado.

O modelo de SGBD como centro do universo já foi substituído há quase vinte anos, uma boa lida sobre componentes e serviços vai te dar uma luz neste tema.

No entanto, se você puder escolher que tipo de abordagem usará, saiba que o que vale é a sua intuição. Não force as coisas. Não deixe de implementar a sua estrutura OO só porque alguém te disse que deveria ser implementado o Design Pattern Xyz. Utilizando o mesmo exemplo do State, se você quer fazer uma enumeração e ficar controlando no teu objeto, faça, se achar melhor cair no mundaréu de leis do State, vá em frente. Tudo se resume a sua intuição. Se alguém disser que pode ser feito de um jeito melhor, sem atrair complexidade e dificuldade de manutenção, mande o cara refatorar o teu código e pronto! Mas, não se assuste em ver gente complicando as coisas sem a mínima necessidade :)

Sim, cada caso é um caso mas acredito que o que deve guiar a escolha técnica não é a intuição e sim a razão, derivada da experiência e estudo das diversas técnicas e práticas, arquiteturais e de design, que foram desenvolvidas pela comunidade de desenvolvedores, acadêmicos, pensadores e práticos por todas estas décadas.

Eu tenho certeza absoluta que você pode me mostrar um monte de coisas super-simples sobre sua área de engines gráficas que eu vou achar mega-complexas sem estudar o motivo pelos quais as coisas são desta ou daquela forma. Por isso que não adianta, plataforma não vence cultura.

Update:

O Vitor colocou um follow-up no blog dele. Como não traz nenhum novo argumento aos pontos aqui levantados além de fazer um bashing sem nenhum argumento concreto em cima de AOP e OO (poxa, até o BileBlog usa alguns argumentos), e cisas estranhas como “eu disse que era impossível porque não faz nenhum sentido gastar tempo e simplicidade implementando esse tipo de coisa”, questionamentos vazios como “por que HQL não implementa todas as funcionalidades da OO?” (Como se Java os implementasse…), tratar um ERP, coração de qualquer empresa, como “coisa menor”, não saber o que é eager fetching e detaching e ainda assim achar os criticar, e, principalmente, este trecho:

Shoes, pergunte para alguém das antigas se ele leu Yourdon e Page-Jones para poder programar. Não leram. Se você for olhar o fonte de alguém das antigas perceberá que tem uma organização. Não é uma OO, mas é tão organizado quanto, e certamente não baixa a produtividade da equipe. Hoje só para programar uma boa OO precisamos ler várias bibliografias, conhecer Design Patterns, e várias outras coisas que você conhece bem. Porquê? Para desenvolver um sistema onde o cara vai cadastrar e ler dados? No máximo um relatório com algumas aglutinações, somas, consultas, limites e etc?

Que me preocupa muito vindo de um estudante de mestrado (além de ser bravata, já que a maioria dos engenheiros de sistems de verdade em algum momento tiveram seu contato com análise struturada/essencial e projeto estruturado).

Eu realmente adoraria ter um debate sadio mas a falta de argumentos e o excesso de factóides, evidências anedotas, falácias e achismos não deixa. Eu realmente tentei mas fico por aqui.

Eu já vi este ponto de vista várias vezes e na grande maioria delas um pouco mais de leitura e experiência ao manter sisteminhas “simples” “de cadastro” que viraram bombas-relógio, vivem mais tempo do que deviam e têm que ser integrados, entendidos, estendidos ou meramente consertados mudaram a perspectiva. Provavelmente é só questão de tempo.

Desenvolvimento Ágil Divertido no XP Rio

Monday, May 21st, 2007

Semana passada fomos Guilherme, Bairos e eu na reunião do XP-RIo. O tema foi um desafio passado pela empresa do Vinicius, a ImproveIt, ao introduzir ao mesmo tempo XP e Ruby on Rails para um departamento de desenvolvimento de software que usava…uhm.. CLIPPER para desenvolver.

Após a explicação de como foi (está sendo, na verdade) feita a “migração do peopleware”, acabamos conhecendo um pouco do estilo que o grupo adotou no seu dia-a-dia. Não vou falar muito porque foram geradas fotos, filmagens e PDFs, que você vê aqui. Vale muito para quem perdeu.

Se você acha que desenvolvimento de software é uma atividade chata e burocrática esta apresentação pode te mostrar que isso não é uma verdade absoluta.

Performance x Pessoas: Compensando Perdas com Infra-Estrutura

Wednesday, May 16th, 2007

Estava conversando com uns amigos e chegamos a uma dúvida bem interessante: por que as empresas acham normal gastar fortunas em infra-estrutura(CPUs, cores, memória, máquinas, RAC, cluster, cache, replicação) e não acham sequer razoável gastar esse investimento para migar para uma plataforma mais eficiente?.

A empresa típica hoje tem na sua linha de frente programadores..uhm… “não-ótimos” para o serviço. Estes programadores geralmente são “adquiridos” por um valor baixo e possuem como característica básica o “trabalho não otimizado” e err… a “rápida depreciação e eventual substituição da mão de obra”.

Ok, sem mais eufemismos porque este blog não se gaba por ser enterprisey: contratam pessoas ruins que ficam pulando de empresa em empresa porque podem pagar pouco (comparado ao preço de um desenvolvedor de verdade) para elas.

E como isso dá certo? Bom, macacos digitando infinitamente não reproduzem a obra de Shakespeare, mas eu garanto que se eles martelarem um teclado por algum tempo eles escrevem boa parte das aplicações Java EE ou .Net criadas hoje em dia. Desenvolvedores ruins sempre existiram mas desde o advento de ferramentas como Visual Basic e Delphi, além de plataformas gerenciadas como Java e .Net se tornou viável contratar um bando deles de largá-los amrtelando teclados sendor egidos por gerentes de pojeto que se gabam de ter sua ‘arte’ surgida na Roma antiga e acabam aplicando práticas de gestão desta época.

Vamos e venhamos: as aplicações criadas na maioria das empresas são estupidamente simples, qualquer zé mané faz. E também na maioria das aplicações basta se comprar um servidor de R$2.000,00 e qualquer aplicação construída por uma menina de 3 anos roda bem que é uma beleza. Claro que a aplicação precisa escalar, ou precisamos ainda já começar pensando grande (pense numa empresa de telecomunicações), se nosso software foi construído por macacos de Shakespeare como podemos fazê-la escalar?

Com hardware.
Máquina. Memória. CPU. Banco de Dados replicado. Particionado. Cache. Quemt em aço e silício dispensa cérebros.

E porque é tão inpensável contratar bons profissionais (que, segundo estudos, podem substituir 10 ou mais code monkeys) e dar a eles uma ferramenta eficaz e eficiente como Ruby/Rails, JRuby/Jython/IronPython/Groovy, PHP, Seaside ou Python?

Por definição uma plataforma de mais alto nível é menos performática mas quase sempre podemos vencer isso na infra-estrutura.

Que tal parar de gastar numa aplicação ruim, que vai dar problema de manutenção frequente, numa plataforma complexa por algo que tem o mesmo custo total, foi feito por 1/10 das pessoas numa plataforma simples?

Update: Faltou a conclusão: por isso que uma empresa de centenas de pessoas e milhares de verdinhas se mata para imitar o que quatro garotos que vivemd e mesada criam nos fins de semana (e não conseguem nem chegar perto!).
Ok, não é por isso, mas é um dos motivos.

Ele Não Aguenta Mais Arroz Com Ovo

Monday, May 7th, 2007

Continuando na nossa série de alertas (não, não era uma série mas acabo de inventar isso) chegamos a um excelente texto sobre o futuro de java x .Net no infoQ. Deste eu destaco:

When .NET was first released in 2000/2001, the Java community considered it a “clone” of Java, both language and standard library. Comparing simple code samples surely support this impression. However, MS profited from many years of experience with Java, and managed to solve some issues that Sun only now realizes as problems. The impression that the .NET and the CLR are evolving faster than Java is not lost on the Java community.

Other examples of this are modularization and versioning, which.NET solved by choosing the assembly, a collection of classes, as the basic deployment unit. Assemblies are equipped with metadata such as version information, unlike Java’s Jar file which lack versioning metadata. This is troublesome for increasingly large applications, which load many libraries. OSGi now provides a solution for this, Sun is busy adding something similar to Java 7.

The Java language keeps on catching up with C#, adding features such as Generics and features such as AutoBoxing, Enumerated types or Annotations. C# now has anonymous expression support, which forms the underpinning of the LINQ technology. LINQ can be thought of a statically typed query language for many different types of data sources, such as XML, relational databases, but also arbitrary object graphs. The Java space, meanwhile, debates language minutiae such as language support for properties and which of four types of anonymous function to include in the language.

The Java space doesn’t really any of the mentioned items, except for the hosting interface, which was added in Java 6, under the name of JSR 223. This is basically just framework to add new language runtimes and initialize and access them in a standardized way.

Jim Hugunin continues with a detailed explanation of how dynamic method dispatch is handled, which makes use of extension methods and other existing CLR systems. The only comparable initiative is JSR 292, which among other things wants to add a new bytecode invokedynamic .This effort was started by Gilad Bracha, who soon after the creation of the JSR, left Sun, and is now not convinced that this project will bring any short term solutions:

Exceto a bizarrice do LINQ, este texto só mostra algo que vem sendo visto diariamente. Provavelmente a JVM e a CLR vão disputar como VMs de linguagens dinâmicas e de DSLs, e tudo mostra uma vantagem técnica para a MSFT. Acordemos.

O Futuro na JAOO

Tuesday, March 20th, 2007

Ótimo painel sobre o futuro da programação no JAOO. Especialmente o comentário do PragDave:

Dave: I’d like to predict that the current stacks of software by 10-15 years are going to be in a much worse legacy and more of a nightmare to maintain. You’re going to have employment forever maintaining this stuff. C++, Java code, C# code, this stuff is very complicated and very brittle with all these class libraries and frameworks. We’re digging ourselves in a really big hole and there will be a lifetime of opportunities for you people to maintain this stuff that you’re creating.

Prepare-se e pense nisso antes de comprar aquela ferramenta mágica ou criar mais um framework que faz a mesma coisa que todos os outros.