Archive for the ‘você.pergunta’ 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.

Cartinha do Leitor

Saturday, March 14th, 2009

Eu basicamente tenho postado “conteúdo original” no meu blog em inglês. Não acho que isso vá mudar tão cedo, então preciso pensar melhor o foco do blog em português. Eu tenho muito interesse em mantêr este blog mas é difícil dividir conteúdo que cai melhor aqui e que cai melhor lá. As vezes é bem óbvio, especialmente quando eu comento sobre o mercado nacional, mas nem sempre.

Então estou pensando em focar mais em posts do tipo “Pergunte ao Calçado”. Eu recebo muitos e-mail com algumas dúvidas bem interessantes e já até publiquei alguns aqui. Eu sei que ultimamente tenho sido uma lesma respondendo meus e-mails mas se você mandar uma mensagem com tópico “Pergunte ao Calçado” meu filtro do gmail vai colocá-lo em uma lista de prioridade mais alta. Não garanto que vá responder e/ou que vá vir a ser publicado aqui mas pelo menos é uma chance bem maior que mandar um email com subject ‘Dúvida’.

Vamos ver se dá certo.

Rastreabilidade em User Stories

Friday, July 18th, 2008

Pergunta na XP-Rio:

Me ajudem no seguinte, no processo unificado, espera-se que todos os casos de uso gerem algum tipo de artefato dentro do projeto. Na verdade, com os casos de uso espera-se chegar em classes que juntas formarão o sistema. Dentro da metodologia existe artefatos que quando feitos, permitem mapear todos os artefatos gerados a partir de um caso de uso. A matriz de rastreabilidade.

Gostaria de saber como o XP permite chegar as classes (código) a partir das User Stories. Por exemplo, dado uma User Stories, quais são as classes geradas para atender essa User Stories?

O XP permite isso? Como é feito?

Provavelmente a primeira coisa a se perguntar é: por que eu precisaria deste dados? Alguns modelos de processo como CMMI definem rastreabilidade, que geralmente é definida nesta linha:

Requirements traceability refers to the ability to describe and follow the life of a requirement, in both forwards and backwards direction (i.e. from its origins, through its development and specification, to its subsequent deployment and use, and through all periods of on-going refinement and iteration in any of these phases.)

- Gotel O.C.Z and Finklestein A.C.W (tirado da Wikipedia)

A necessidade parece justa e real, é preciso saber quais partes do software são afetadas por mudanças no negocio e vice-versa. O grande problema desta métrica é que transformações de modelo não são mais tão drásticas há algumas décadas. Ao utilizar qualquer tecnologia relativamente comum (Java, Ruby, .Net, Python, JavaScript…) não existe motivo técnico para que o software não modele o negocio em uma relação próxima de 1-para-1, desta forma saber qual parte de um código realiza qual tarefa torna-se bem simples.

Outro problema é que eu nunca vi um artefato de rastreabilidade, seja qual for, que não ficasse defasado. Se você abraça uma metodologia ágil sabe que refactoring faz parte da vida.

Mesmo com todos os problemas que esta métrica possui eu entendo que existem casos onde seu uso se faz necessário –especialmente por equipes tentando introduzir agilidade em ambientes tradicionais. Supondo que exista uma necessidade justificável para algum controle deste tipo, metodologias ágeis em geral possuem um mecanismo muito mais eficiente que documentos ou mesmos sistemas: testes.

Toda história, todo cartão, deve ter um critério de aceite. O critério de aceite traz o que o cliente considera ser o mínimo para que a história seja considerada concluída. Por exemplo:

História: Como administrador eu quero criar um novo grupo para que possa aplicar permissões à diversos usuários de uma só vez.
Critérios de Aceite:

  • O novo grupo criado deve possuir o usuário que o criou como seu administrador
  • O novo grupo não deve conter outros membros
  • O novo grupo não deve ser visível na listagem de grupos

Cada um destes critérios via um teste unitário e/ou funcional que é executado como parte da integração contínua. Para saber exatamente quais classes e códigos são afetados por cada um deles é simples: use uma ferramenta de test coverage como o Emma e execute apenas os testes de aceitação para aquele cartão. A ferramenta irá gerar relatórios como estes:

[class, %]	[method, %]	[block, %]	[line, %]	[name]
25%  (1/4)!	25%  (3/12)!	40%  (3012/7446)!	25%  (3/12)!	com.sun.tools.javac.v8.resources
94%  (16/17)!	49%  (41/83)!	48%  (1111/2292)!	45%  (201.1/450)!	com.sun.tools.javac.v8
88%  (45/51)!	61%  (242/397)!	54%  (3070/5729)!	52%  (809.6/1563)!	com.sun.tools.javac.v8.tree

Classes que possuem alguma cobertura foram afetadas pelo teste, logo são parte da execução daquela história. Não é difícil escrever um script que –talvez como parte do build- processe estes relatórios e gere o artefato de rastreabilidade que seu processo te obrigar a fazer. Melhor ainda: este artefato nunca estará desatualizado.

Só não se esqueça que melhoria contínua é um conceito importante. Se o artefato de rastreabilidade é algo tão ineficiente a obrigação de um desenvolvedor que perceba isto é mostrar para sua organização que o valor desta pratica é nulo. Não se acomode.

Nem só de troca de mensagens vivem os objetos

Sunday, May 25th, 2008

Percebi que boa parte das dúvidas quanto ao meu post sobre como objetos não possuem atributos se deve ao fato das pessoas não terem geralmente um conhecimento real sobre o que é troca de mensagens.

Perfeitamente compreensível. Na maior parte dos livros e faculdades as pessoas aprendem que Orientação a Objetos é sobre como utilizar classes e sobre como as funções são chamadas de métodos. Por algum motivo esquecido nas areias do tempo decidiu-se que chamar o método em uma classe era passar uma mensagem e por isso algumas pessoas notoriamente pedantes usam este termo ao invés de dizer apenas “chama a função”.

Bem, os conceitos no parágrafo acima estão errados. Orientação a Objetos não é sobre classes e sim sobre…er… objetos. Você pode ter OO sem ter classes, como JavaScript e Io e pode ter também OO sem mensagens.

Troca de mensagens é um conceito utilizado em diversas áreas, não apenas Orientação a Objetos. Você pode ter um Sistema Operacional baseado neste conceito -como o MINIX por exemplo- ou criar uma arquitetura de computação distribuída como SOAP.

O que distingue a passagem de mensagens é o fato de que o recipiente da mensagem, seja um objeto, um serviço ou um processo, é quem decide o que é feito em decorrência de sua invocação.

Para tentar içar um pouco mais claro eu criei um meta-modelo bem bobinho em Java. Este representa um sistema Orientado a Objetos com classes e passagem de mensagens. O código abaixo mostra como declarar uma Classe calculadora e enviar uma mensagem dizendo para que esta multiplique números.

BlocoDeCodigo bloco = new BlocoDeCodigoImpl<Integer, Integer, Integer>(){
			public Integer executar(Integer a, Integer b){
				return a * b;
			}
		};

		Classe classeCalculadora = novaClasse("Calculadora");
		classeCalculadora.declaraMensagem("multiplique", bloco);

		Instancia calculadora = instanciar("Calculadora");

		assertEquals(8, calculadora.enviaMensagem("multiplique", 2, 4));

Note os passos realizados. Primeiro criamos um bloco de código, uma função. Depois dizemos ao sistema que existe uma classe chamada calculadora. Logo apos registramos o fato de que calculadora responde a uma mensagem executando o bloco que havíamos declarado.

Em termos de semântica, este código é mais ou menos equivalente a este:

public class Calculadora{
 public Integer multiplicar(Integer a, Integer b){
  return a * b;
}
}

Depois nós instanciamos a classe e passamos uma mensagem para ela, o que seria equivalente a:

Calculadora calc = new Calculadora();
calc.multiplicar(2,4);

As classes relevantes:

public class Ambiente {
	static Map<String, Classe> classesDeclaradas = new HashMap<String, Classe>();

	static Classe novaClasse(String nomeDaClasse) {
		ClasseImpl classe = new ClasseImpl(nomeDaClasse);
		classesDeclaradas.put(nomeDaClasse, classe);
		return classe;
	}

	static Instancia instanciar(String nomeDaClasse) {
		return new Instancia(classesDeclaradas.get(nomeDaClasse));
	}
}

public class ClasseImpl implements Classe {

	private final String nome;

	private Map<String, BlocoDeCodigo> mensagens = new HashMap<String, BlocoDeCodigo>();

	public ClasseImpl(String nome) {
		this.nome = nome;
	}

	public void declaraMensagem(String nomeDaMensagem, BlocoDeCodigo blocoASerExecutado) {
		mensagens.put(nomeDaMensagem, blocoASerExecutado);
	}

	public String nome() {
		return nome;
	}

	public boolean respondeA(String nomeDaMensagem) {
		return mensagens.containsKey(nomeDaMensagem);
	}

	public BlocoDeCodigo codigoParaMensagem(String nomeDaMensagem) {
		return mensagens.get(nomeDaMensagem);
	}

}

public class Instancia {
	private final Classe minhaClasse;

	public Instancia(Classe classe) {
		this.minhaClasse = classe;
	}

	public Object enviaMensagem(String mensagem, Object... args) {
		Object primeiro = args.length > 0 ? args[0] : null;
		Object segundo = args.length > 1 ? args[1] : null;

		return minhaClasse.codigoParaMensagem(mensagem).executar(primeiro,
				segundo);
	}

	public Classe classe() {
		return minhaClasse;
	}

}

Esse meta-modelo é baseado em troca de mensagens. A classe Calculadora não recebe código a ser executado ela apenas recebe o nome de uma mensagem e parâmetros. Imagine que eu registre o mesmo bloco de código para várias mensagens, ou que eu use recursos de AOP e intercepte a execução do bloco. Nada disso é relevante para quem invoca a mensagem, ele apenas a envia e o que acontece em decorrência disso é responsabilidade do receptor.

Como quase todas as linguagens atuam desta forma pode ser difícil entender o conceito já que nunca se viu nada diferente. Vamos então implementar outro meta-modelo que não usa troca de mensagens mas sim uma outra forma chamada Data-Directed.

Nesta forma de invocar operações em objetos –que, como a anterior não é específica de OO- quem decide qual função será aplicada é o ambiente de execução, o runtime. Quando você invoca uma operação o ambiente vai procurar dentre os métodos registrados qual é o aplicável para aquele objeto e vai executar o método nele. Common Lisp utiliza este recurso de maneira tão poderosa em suas Generic Functions que praticamente elimina a necessidade de coisas como proxies e AOP.

Nosso meta-modelo para Data-Directed é executado dessa forma:

BlocoDeCodigo bloco = new BlocoDeCodigoImpl<Integer, Integer, Integer>(){
			public Integer executar(Instancia instancia, Integer a, Integer b) {
				return a * b;
			}
		};

		Classe classeCalculadora = novaClasse("Calculadora");
		registrarMetodo("multiplique", classeCalculadora, bloco);

		Instancia calculadora = instanciar("Calculadora");

		assertEquals(8, executarMetodo("multiplique", calculadora, 2, 4));

Repare que agora o bloco de código recebe como seu primeiro argumento uma referência para a instancia a qual se aplica (se você já usou java.lang.Method sabe que isso não é incomum quando se desce ao nível de implementação de linguagem). Caso nosso exemplo fosse minimamente usável seria desta forma que o bloco obteria acesso ao objeto em si.

Logo depois criamos a classe como antes mas ao invés de registrar uma mensagem na classe nós registramos um método no ambiente, dizendo que o método se aplica àquela classe. A invocação em si é bem parecida com a anterior.

Na implementação a única classe mais interessante é o Ambiente, que agora é bem mais esperto:

public class Ambiente {
	static Map<String, Classe> classesDeclaradas = new HashMap<String, Classe>();
	static Map<String, Map<Classe, BlocoDeCodigo>> metodos = new HashMap<String, Map<Classe, BlocoDeCodigo>>();

	static Classe novaClasse(String nomeDaClasse) {
		ClasseImpl classe = new ClasseImpl(nomeDaClasse);
		classesDeclaradas.put(nomeDaClasse, classe);
		return classe;
	}

	static Instancia instanciar(String nomeDaClasse) {
		return new Instancia(classesDeclaradas.get(nomeDaClasse));
	}

	static void registrarMetodo(String nomeDoMetodo, Classe tipoEmQueSeAplica,
			BlocoDeCodigo bloco) {
		metodo(nomeDoMetodo).put(tipoEmQueSeAplica, bloco);
	}

	static Object executarMetodo(String nomeDoMetodo, Instancia instancia,
			Object... args) {
		Map<Classe, BlocoDeCodigo> tiposAceitaveis = metodo(nomeDoMetodo);
		if (!tiposAceitaveis.containsKey(instancia.classe()))
			throw new RuntimeException("Metodo inexistente");

		BlocoDeCodigo bloco = tiposAceitaveis.get(instancia.classe());

		Object primeiro = args.length > 0 ? args[0] : null;
		Object segundo = args.length > 1 ? args[1] : null;

		return bloco.executar(instancia, primeiro, segundo);
	}

	private static Map<Classe, BlocoDeCodigo> metodo(String nomeDoMetodo) {
		if (!metodos.containsKey(nomeDoMetodo))
			metodos.put(nomeDoMetodo, new HashMap<Classe, BlocoDeCodigo>());

		return metodos.get(nomeDoMetodo);
	}

}

Agora não apenas registra as classes mas também os métodos que são aplicáveis à cada classe e faz a invocação dos métodos em si.

Estes exemplos são bem educacionais, sem muita aplicação pratica, mas como já vimos em posts passados o fato de se usar message-passing ou Data-Directed ou properties, ou componentes ou qualquer outra coisa interfere no modo como devemos projetar nosso software. Existe uma vasta literatura sobre este tema mas ainda assim é uma das coisas mais desconhecidas pelo programador profissional.

Australian Architecture Forum 2008

Thursday, May 1st, 2008

Falando em coisas agitadas, fui convidado para palestrar no Australian Architecture Forum 2008. O título é “Lightweight SOA Through Web Widgets” e falar de SOA com REST num evento onde vai estar presente o impagável Jim Webber é algo bem diferente.

Como meu Google Analytics diz que ese blog é acessado por pessoas aqui na Austrália fica o convite.

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.

Quando eu crescer quero ser Analista de Sistemas

Tuesday, January 15th, 2008

Este tópico está na minha fila de posts há meses, hora de sair algo. Eu vou me basear num e-mail que recebi de uma pessoa do GUJ (cujo nome não será mencionado pois não pedi autorização para tal):

Sobre o “polêmico” manjado tópico de que o java pode acabar.

Você postou o seguinte (na primeira página):

Software é programar. Se você que gerenciar uma equipe de desenvolvimento você tem que estudar matérias relacionadas à gestão de pessoas. Isso não é uma evolução do programador, um desenvolvedor de software é sempre um desenvolvedor de software.

Será que alguém que se forma em Ciência da Computação (como eu, se Deus quiser) não consegue o cargo de gerência de equipe? Eu vejo isso pelo meu tio… ele é formado em Engenharia Química e hoje é gerente de um empesa aqui, mas porquê? Porque ele conhece como as coisas funcionam… todo gerente que conheço ou que já ouvi falar aconteceu o mesmo… gerentes de supermercado geralmente sabem tudo o que se passa dentro do maldito mercado! Concorda? Logo, começa-se como programador, pra depois passar pra cima. Ou não? Você já foi programador? Estou em dúvida porque parece que o salário de um programdor (caso eu seja programdor pra vida inteira, que é algo que eu não quero) é baixo e não dê pra sustentar uma família, entende? Da maneira que eu digo faz parecer que eu não quero ser programador JAMAIS, mas eu quero… putz, amo programar, tenho um tesão gigantesco por programação… mas o problema é se vai me sustentar bem e minha família pro resto da vida, entende? Acredito que se um dia eu chegar a um cargo que não envolva programação eu ainda assim vou programar, pra me divertir mesmo.

E aí, o que você acha?

Este é um problema bem grande. Vamos começar sobre algo que não está explícito no e-mail acima mas que existe: aquilo que alguns chamam de analista de sistemas.

Quando eu estava na faculdade pela primeira vez (ou seja: antes de abandoná-la pela primeira vez) lembro de ter aula com um daqueles professores com anos de COBOL nas costas. Ele se lamentava sobre como o mercado confundia analistas e programadores e como estava surgindo a bizarrice do ‘progranalista’- alguém que combinava os dois papéis. Na comunidade em geral você vê este pensamento, eu tenho muitos conhecidos que querem ser ‘analistas’, e isto para eles significa desenhar UML ou fluxogramas que são passados para os programadores.

Creio que já tenha escrito sobre este assunto neste blog mas, resumindo, não há justificativa para este papel existir no desenvolvimento de sistemas nos últimos dez anos. O papel do analista seria, teoricamente, converter um modelo abstrato (de negócios) em um modelo lógico, geralmente expresso de forma gráfica. O modelo lógico então passa a um modelo físico, que é a implementação.

Agora vamos analisar o caso de uma plataforma moderna de desenvolvimento como Java, .Net ou Ruby - ‘moderna’ aqui significando algo como “inventada nos últimos dez anos”. Um modelo abstrato é composto por conceitos de negócio. Geralmente estes conceitos não possuem uma estrutura que um computador entenda, logo o analista vai traduzir este conceito em lógica, provavelmente usando UML. Ora, UML é apenas uma notação gráfica para classes e objetos, e sua linguagem favorita já trabalha com classes e objetos! A tradução entre um modelo lógico e o modelo físico é desnecessária: o modelo lógico já é o modelo físico. A diferença é que UML não executa, por mais que os evangelistas de MDA cismem do contrário.

A solução? Modele em código. Caso seja necessário gerar diagramas basta utilizar uma das dezenas de ferramentas de engenharia reversa. Modelando em código você tem algo executável, testável e que pode dar feedback ao seu usuário.

“Analista de sistemas” é algo que não existe. Pode ter existido um dia, não sei, mas não faz mais sentido há muitos anos. O modelo lógico é expresso em linguagens de alto nível que modelam muito bem o negócio: Java, Ruby, C#… Quem converte o lógico em físico é o compilador, que traduz as abstrações em código de máquina.

Alguém colocar na sua assinatura de e-mail ou ter a carteira assinada (como eu já tive!) como “Analista Java” está se enganando e colaborando para a criação de papéis que só existem na burocracia das empresas e das pessoas.

Ok, sem diagramas de objetos então, mas e a parte do papel do analista de resolver problemas de negócio? Sinto informar mas se você fazia isso como parte das suas tarefas de “analista de sistemas” você estava ou se enganando ou enganando seu cliente. É certo que muitos clientes precisam entender seus próprios negócios antes de criar um sistema, mas isso não é papel de analista de sistemas, é papel de analista de negócios.

Um analista deste tipo possui capacitação em campos bem diferentes, é completamente possível que um analista de negócios seja um desenvolvedor (vamos abolir o “analista de sistemas” a partir daqui) mas neste caso ele está assumindo duas especialidades. Um analista de negócios possui um perfil não-técnico e provavelmente mais especializado em um domínio como bancos, marketing, telecomunicações e etc.

Mas e o gerente? Uma das piores coisas que podem fazer em uma empresa é promover um bom técnico à gerente (coordenador, o que for) apens porque ele está há muito tempo na casa. Querem estimular a pessoa? Transormem em um líder técnico, aumentem seu salário e o deixem em paz.

Gerência não é brincadeira. Não é porque alguém programa muito bem que vai ser um bom gerente. Se você é desenvolvedor mas sonha em dizer para a paquera no barzinho que é gerente de algo (nem que seja do McDonald’s) invista nisso. Aprenda sobre liderança, sobre mercado, plano de negócios, luxo de caixa, lean e todas as dezenas de disciplinas envolvidas. Vai levar algum tempo.

Só não encare isto como uma evolução. Você não está evoluindo, está mudando de carreira -da área técnica para a gerencial. Considerando que conseguir bons salários como técnico é complicado, pode ser uma boa escolha. Mas não necessariamente é a melhor escolha, se você é um bom técnico e não quer deixar isso de lado existem opções…

Arquiteturas Simples Duram Mais

Wednesday, October 24th, 2007

Um amigo outro dia me perguntou que tipo de arquitetura eu usaria num caso bem peculiar. Basicamente ele foi encarregado de definir a arquitetura corporativa de um grande banco, ou seja: definir hoje a forma como aplicações serão construídas pelas próximas décadas. Basicamente ele vai se ro cara que vai ser xingado por algumas centenas de programadores nos próximos tempos, não importa que arquitetura escolha.

Há poucos dias atrás falamos aqui sobre arquiteturas de referência e seu efeito danoso. Geralmente quando alguém tem à frente um desafio desse ele logo pensa em um modelinho que mostra obriga o uso de uma meia dúzia de frameworks e padrões (clássico moderno: Struts/JSF e JPA, clássico vintage: Struts 1.1 e EJB/DAO). Para melhorar ainda é incorporado um conjunto de classes “utilitárias” feitas com práticas que talvez tenham servido para um projetinho piloto mas hoje em dia só atrapalham.

Ainda assim uma arquitetura corporativa é algo interessante. Quando empresas grandes não possuem uma macro-arquitetura acabam crescendo de maneira desordenada e criando dezenas de aplicações redundantes e gambiarras de integração entre sistemas. Note no entanto que uma arquitetura corporativa não é uma arquitetura de referência, a arquitetura corporativa não fala sobre como implementar aplicações mas sim provê guias sobre como integrá-las, define as relações previstas em no ecossistema que é uma grande empresa.

Quais são as melhores macro-arquiteturas que você conhece? Eu consigo pensar em algumas: Apache, UNIX, World Wide Web… Nestes ecossistemas aplicações novas surgem, são alteradas e morrem todos os dias há décadas, um sistema criado com a tecnologia mais recente de 2007 vai rodar tranqüilamente neste ambiente. Por quê?

Porque estas arquiteturas se baseiam em primitivas e contratos, não em especificações rígidas. Criar um módulo para o Apache , um programa para rodar em UNIX ou uma site é basicamente criar um programa de computador em uma das plataformas suportadas que obedeça a um contrato.

Uma boa arquitetura corporativa vai definir algumas políticas e contratos para a aplicação se relacionar com o meio-ambiente e só isso. No caso do banco, poderíamos definir que uma aplicação deve disponibilizar via uma interface POX/REST seus WebServices, que ela deve utilizar a API do Mogile FS para guardar dados em disco, que cache deve ser feito utilizando a API do memcached.

E se o arquiteto quiser sair do padrão? Ótimo, saia, mas ele deve oferecer compatibilidade com o ambiente.

E se eu já tiver comprado um sistema que faz WebServices via SOAP? Eu preciso criar um meio de disponibilizar estes serviços via POX/REST também. Pode ser uma adaptador simples, um ESB, o que quer que seja. É como quando você compra um equipamento eletrônico com tomada americana, você não vai mudar uma tomada na sua casa para o padrão exótico, vai é comprar o adaptador necessário para plugar ele nas tomadas do seu ambiente.

Mas e se não precisarmos de filesystem distribuído? E se já estivermos utilizando uma solução de cache que faz mais sentido nesta aplicação?

Ótimo, use. O uso de filesystem X, cache Y, banco de dados Z deve ser um guia. Toda vez que alguém precisar de uma solução de cache, filesystem, etc. ele olha o guia da empresa, se não servir ele usa algo que sirva. O que importa é que o uso fique encapsulado no sistema. Imagine que ao invés do Oracle 10g eu resolva usar um MySQL na minha aplicação. Está ótimo mas eu devo manter essa peculiaridade interna à minha aplicação. Os outros sistemas que vierem a se comunicar com o meu não devem precisar saber sobre a existência deste banco, eu não posso usar este banco para comunicação entre aplicações (o que já é uma coisa péssima para se fazer de qualquer forma).

O que importa é:

  1. O arquiteto tem liberdade para resolver seu problema da maneira mais adequada
  2. O novo sistema é compatível com o meio-ambiente

Para ser um bom arquiteto não é necessário ter tanta experiência assim, basta saber olhar os casos de sucesso e aproveitar o que funciona. Geralmente as técnicas utilizadas nestas arquiteturas são também catalogadas como Padrões Arquiteturais em livros. Um bom arquiteto tem que ser um ávido leitor de livros e de código.

Sobre Entrevistas

Monday, October 22nd, 2007

Há mais de dois anos que entrevistar candidatos faz parte do meu dia-a-dia. Neste período eu aprendi bastante sobre como entrevistar e ser entrevistado, acho que é um bom momento para compartilhar… não estou dizendo que o texto abaixo é ótimo, é aplicável ao seu caso, ou sequer que você deva usar. É apenas uma descrição sobre o que eu tenho de experiência nesta área.

Lição 1: Seja Claro no que Procura

Não são só arquiteturas que sofrem com padronização desnecessária, entrevistas também devem ser desenhadas de acordo a situação, especialmente com o que se espera encontrar.

É preciso saber o que se procura. Geralmente alguém decide que a equipe precisa de mais um ou mais membros para ter melhor performance mas a primeira coisa a fazer -como sempre- é fugir do senso comum e se perguntar: é isso mesmo? Será que estamos fazendo as coisas certas? Será que não podemos melhorar nosso desempenho simplesmente mudando a forma de trabalho? Empresas de três letras ensinaram ao mercado que quando um projeto vai mal devemos enfiar pessoas nele (e cobrar por homem/hora, não se esqueça) mas isso é simplesmente contra tudo que sabemos sobre projetos de software. Enfiar mais pessoas em um projeto só o faz atrasar mais (leia Fred Brooks).

Se a resposta for realmente mais pessoas, então que tipo de profissional precisamos contratar? Seja lá o que for deixe bem claro no anúncio, você não vai evitar que panfletadores de curriculum encham sua caixa de email (aliás, crie uma caixa só para isso e desative-a quando não existirem mais vagas) mas vai melhorar as chances que alguém realmente interessante e interessado responda. Também não coloque em qualquer lugar seu anúncio, divulgue em listas especializadas e em grupos de pessoas que confie. Aliás, grupos de pessoas são ótimos porque você pode verificar o histórico da pessoa que enviar o curriculum.

Lição 2: Capriche na Triagem

Se você for bem específico como sugeri na lição acima dificilmente vai ter uma chuva de curriculums, mas caso tenha uma técnica de triagem se faz necessária. Se você tem tempo faça a primeira entrevista por telefone. Se você não tem muito tempo sequer para entrevistas presenciais faça o seguinte: crie uma lista com alguns problemas e peça para o cara resolver e te mandar a resposta.

Os problemas precisam ser diferentes, crie um problema sobre concorrência, um sobre otimização, um sobre modelagem, eles precisam ter o mesmo nível de dificuldade também. O problema que a pessoa escolher (só deve escolher um) te diz sobre o perfil dela. Depois faça uma revisão via telefone do código com a pessoa, é mais para evitar fraude mas ainda assim é uma ótima oportunidade para perguntar alguns aspectos técnicos, porque tomou a decisão X e não fez Y, como refatorar a solução para que fique mais XYZ, etc.

Lição 3: Nada de Perguntas McDonald’s

Para entrar numa grande empresa fui entrevistado pelo meu futuro gerente. Ele tinha na mão uma lista com umas 10 páginas de perguntas variadas sobre Java e SQL, basicamente. Após a segunda página nós já havíamos abolido a folha e partido para um fluxo mais aberto de conhecimento mútuo. Dessa experiência eu tirei um fluxo de entrevista um pouco diferente do que costumo ver.

Quando seleciono um curriculum eu geralmente monto um estereótipo para aquela pessoa: “Arquiteto”, “junior”, “pleno”, “especialista em XXX”, “enrolão”, etc. Deste estereótipo eu penso em algumas primeiras perguntas.

Quando a pessoa chega eu geralmente peço a ela que se apresente, conte um pouco da sua história. Desta o estereótipo inicial pode ser alterado ou não, geralmente após isso eu já tenho uma boa noção do perfil profissional da pessoa. Aí começam as perguntas reais.

Se eu penso que o cara é junior eu começo com algumas perguntas pedindo para ele descrever conceitos. Eu dificilmente pergunto pelo conceito diretamente mas sim algo que indiretamente vai requisitar dele que o faça, como comparações. Continuando com conceitos eu vejo se possui boas bases ou é apenas apertador de parafusos. Eu continuo perguntando, seguindo os perfis de pleno, arquiteto e especialista até ver que o cara não sabe mais. Muitas vezes encontrei juniores que sabiam mais que arquitetos.

Para “desenvolvedor pleno” a coisa começa relativamente ao contrário. Eu peço para ele descrever alguma coisa em que tenha trabalhado e depois para ele dissecar a arquitetura. No meio do caminho surgem diversos pontos interessantes para explorar como Domain Models, BO/VO, programação concorrente, técnicas de performance, etc. Sempre que possível eu faço perguntas baseadas em um cenário real que eu já tenha vivido, até para a pessoa sentir o tamanho do desafio (é difícil fazer alguns entenderem o tamanho da encrenca). Muita gente morre aqui simplesmente porque não entende nada do que trabalha. O cara está há anos desenvolvendo aplicações e não tem idéia do porque usa um padrão ou outro. Todo mundo sabe responder “um design pattern é uma solução para um problema comum blablabla” mas ninguém sabe dizer que problema o tal do BO/VO soluciona.

Tenho que admitir que para arquitetos o buraco é way over mais embaixo. A coisa começa com descrições sobre arquiteturas que ele já tenha trabalhado e, principalmente, desenhado. Geralmente nestas descrições vai haver uma menção um pouco mais interessante que o usual, como conectores JCA, filas, caches ou clusters. Aí é que está o pulo do gato: um arquiteto tem que saber como isso funciona num projeto. Não importa se na época ele não se entitulava arquiteto, não é admissível alguém que nunca parou para saber como aquilo funcionava! Algumas perguntas sobre arquitetura da JVM são sempre boas também. Você consegue descrever como o Garbage Collector funciona com muita e com pouca memória disponível? Identificar erros mais simples de parametrização da JVM?

Interessante notar que não é preciso responder certo as perguntas. Aliás, eu nem espero que sejam respondidas. As respostas ideais, da melhor para a pior:

  1. Resposta certa
  2. Caminho certo (não chegou na resposta mas elaborou bem)
  3. Resposta errada por uma bobeira qualquer
  4. Dizer que não sabe

Nessa lista não está a resposta errada. Se um candidato não assume que não conhece a resposta (e algumas perguntas não supõem que você conheça a resposta!) e chuta ele perde muitos pontos numa entrevista dessa. Mentir sobre projetos e empresas é sempre engraçado, no Rio de Janeiro eu conheço muita gente em muitas empresas e sempre consigo lembrar de alguém que teoricamente teria trabalhado com o candidato no tal projeto.

Eu sempre insisto para a pessoa tentar chegar na resposta ao menos. Na sala sempre vai haver papel e caneta ou um quadro-branco, o ato de seguir por um caminho lógico para tentar chegar à resposta é muito importante. Uma das coisas que consigo verificar assim é escalabilidade, dificilmente aparece alguém que sabe como criar um site que suporte um fluxo muito grande de acessos mas geralmente as pessoas têm pelo menos uma idéia sobre conceitos que podem usar enste caso.

Tem gente que fica muito nervosa neste ponto então é melhor criar o ambiente mais descontraído possível. Aqui isso não é problema, geralmente eu converso com a pessoa com meu jeans e camiseta usual, muitas vezes com o pé na cadeira. Não é para impressionar, é assim que as coisas são e é bom a pessoa saber disso. Eu não quero saber se a pessoa é boa ou ruim, quero apenas saber se ela é quem eu estou procurando neste momento ou não.

Lição 4: Explique o Cenário

Após a entrevista em si eu explico o cenário. Descrevo como as coisas funcionam na equipe, a hierarquia, os tipos de projeto, tecnologias e o que espero da vaga. No final respondo dúvidas.

Por que não antes? Porque pode influenciar a pessoa. Ao ouvir que nós plantamos bananas ele vai se vender como o melhor bananeiro desde Jorge Ben Jor.

Lição 5: Racionalize o Candidato

As vezes você procura um semi-deus e aparecem apenas juniores, as vezes você procura juniores e o próprio Zahl aparece. Hoje em dia um gestor tem que saber flexibilizar seu quadro de pessoal.

Se você tem vaga de senior e arrumou um junior muito interessante que tal dividir a grana do senior em dois? Ou que tal pagar o salário do junior e com o resto do orçamento investir na equipe para que todo mundo suba de nível técnico?

O tipo de entrevista acima não dispensa ninguém. Se na segunda pergunta você já viu que o cara não serve para a vaga continue, descubra quem o cara é. Num mercado como esse no mínimo você pode indicá-lo a outro gestor precisando de pessoas ou guardar na manga para outra oportunidade. Claro que se o cara for ruim ele é ruim e pronto.

Eu sei bem que não é o ideal, mas este modelo de entrevista já me fez boas contratações e, sinceramente, nenhuma ruim. Um dos efeitos ruins é que as vagas demoram bons meses para serem preenchidas mas atualmente isso é “menos pior” do que ficar meses com um desenvolvedor não-qualificado.

Objetando: Objetos e o Mundo Real

Saturday, June 16th, 2007

E-mail do Caike:

Olá Phillip, tudo bom ?

Leio sempre seus posts em seu blog e no fórum do GUJ e vejo como algumas vezes suas constatações vão por caminhos diferentes dos do ’senso-comum’ (Freakonomics?). Gostaria de agradecer as ‘guerras’ (inclusive algumas vezes levadas muito mais a sério do que deveriam, por outras pessoas) sobre diferentes arquiteturas e aplicações de OO. Graças a elas, tenho ganho diversos pontos a serem investigados em meus estudos.
Sou recém graduado em Ciência da Computação por uma faculdade de Belém, PA, e a pergunta que estou prestes a fazê-lo envolve a tâo polêmica orientação a objetos.

Batendo a cabeça sobre tudo o que o pessoal vem falando e a idéia que você vem tentando passar, gostaria que avaliasse a minha possível avaliação de OO.

Vejo a OO como algo que tenta expressar mais como o mundo real funciona, e não como ele realmente é. Acredito que o foco da abordagem orientada a objetos deva estar nas mudanças de processos e, por conseqüência desta, acaba dando uma idéia de como as coisas são. Durante a modelagem de uma idéia devemos prezar pela situação que melhor expressar seu funcionamento, e não sua estrutura. A grosso modo: Se nosso sistema resolve um problema relativo a segurança de uma casa em Brasília, não deveríamos nos preocupar com a ameaça de um marémoto. Não devemos fazer nossos objetos serem capazes de fazer coisas que eles não vão precisar fazer. Um pensamento como este construirá uma boa arquitetura que terá sempre a robustez para se adequar a mudanças, ou, complementos de atividades.
Parabéns pelos posts e espero estar pensando de maneira coerente.
- Caike

Este é um ponto deveras interessante, como diria um grande amigo.

Orientação a Objetos é pura e simplesmente um conceito técnico. É pegar dados e lógica e manter num mesmo componente, seja através de classes ou qualquer outra forma (por isso tanta gente se espanta quando descobre que JavaScript é OO). É por isso, por exemplo, que Ma href=”http://www.objectmentor.com/ “>Uncle Bob introduz sua apresentação sobre design eliminando o mito de que “objetos modelam melhor o mundo real” e focando sua utilidade em gerenciamento de dependências.

Alan Kay, inventor de Smalltalk e um dos pioneiros na área (ele criou o termo object-oriented descreve em seu paper “The Early History of Smalltalk”:

In computer terms, Smalltalk is a recursion on the notion of computer itself. Instead of dividing “computer stuff” into things each less strong than the whole–like data structures, procedures, and functions which are the usual paraphernalia of programming languages–each Smalltalk object is a recursion on the entire possibilities of the computer. Thus its semantics are a bit like having thousands and thousands of computer all hooked together by a very fast network. Questions of concrete representation can thus be postponed almost indefinitely because we are mainly concerned that the computers behave appropriately, and are interested in particular strategies only if the results are off or come back too slowly.

Para Kay, objetos são mini-computadores especializados em um conjunto específico de comportamentos. A idéia do autor era utilizar estes mini-computadores para aproveitar os recursos das máquinas mais eficientes dos anos 70.

Com o passar do tempo surgiu outro tipo de profissional, o que não estava mais tão preocupado assim em resolver problema computacionais mas sim em como a tecnologia pode ajudar seus clientes (este é o elo perdido entre os programadores e os pseudo-analistas de sistemas de hoje). As pessoas desta linha de pensamento começaram a fazer paralelos entre objetos e conceitos do mundo real e perceberam que podiam utilizar as boas características da OOP (herança, encapsulamento, contratos…) para modelar o domínio de um software.

Por isso um objeto serve para modelar o processo de negócios de uma empresa de uma maneira relativamente eficiente (pelo menos mais eficiente que abordagem de programação estruturada) assim como serve para modelar um Servlet, algo completamente tecnológico sem paralelo no domínio de negócios. Ambos, Servlet e objetos de domínio, tiram proveito das características de OO.

Esta falta de relacionamento real entre OO e “modelar o mundo” dá uma pista de que você está no caminho certo. Abstrair é tirar detalhes não-interessantes dentro de um contexto. Quando abstraímos algo nós nos concentramos apenas no que é necessário para fazer o que precisamos, é como quando eu falo para você “meu vôo sai assim que o sol nascer”. O vôo não é meu e ele não depende do Sol nascer para partir, mas você entendeu a mensagem mesmo abstraindo os detalhes. Objetos servem para modelar, seja br.com.empresa.Pedido ou javax.swing.JButton de forma abstraída.

Note que OO nem sempre é o ideal. Cada domínio já desenvolveu na sua história meios para modelar seu domínio. Pense no sempre utilizado exemplo de contabilidade. Por séculos os contadores utilizaram estruturas tabulares para efetuar seus cálculos, estruturas que evoluíram até planilhas eletrônicas como a Google Spreadsheet ou OpenOffice.org Calc. A tecnologia evolui e talvez estes modelos caiam, mas se você se manter próximo destes paradigmas vai conseguir muito mais satisfação ao lidar com usuários. Por isso os domínios expostos com orientação a objetos estão sendo desafiados por domínios expostos por Domain-Specific Languages (DSLs).

Seu exemplo, entretanto, foge mais do conceitual sobre modelagem e entra em princípios de processo de desenvolvimento. Se você mostrar este exemplo para algumas pessoas elas certamente dirão “Ah, mas amanhã pode ser que a empresa venda o produto para alguém no Rio, ou pode ser que o Sertão vire Mar e o Mar vire Sertão. O que fazer neste caso? YAGNI. Implemente o que você precisa agora, deixe o amanhã para amanhã. Claro que é papel fundamental de um bom arquiteto (e não, arquiteto não é aquele cara que faz diagrama o dia inteiro, na maioria dos projetos todos somos arquitetos em maior ou menor nível) é prever possibilidade de extensão e flexibilidade, mas a minha experiência diz que a melhor maneira de criar flexibilidade sem overengineering é utilizar um ótimo design OO.