Design de software

A essência da OOP é a troca de mensagens: a verdadeira OOP segundo Alan Kay

Ao estudar OOP, sempre começamos decorando três palavras: herança, encapsulamento e polimorfismo.

4 min de leitura
Imagem de capa de A essência da OOP é a troca de mensagens: a verdadeira OOP segundo Alan Kay

A essência da OOP é a troca de mensagens: a verdadeira OOP segundo Alan Kay

Ao estudar OOP, sempre começamos decorando três palavras: herança, encapsulamento e polimorfismo.

Mas Alan Kay, que criou o termo “programação orientada a objetos”, não considerava esses três conceitos o núcleo.

Vamos ao ponto: para Alan Kay, a essência da verdadeira OOP são as mensagens trocadas entre objetos, não os objetos em si. Antes de dividir classes, é preciso pensar no que os objetos trocam.

Ao final, você entenderá por que ele chegou a dizer que “se arrependia do nome orientado a objetos” e como essa perspectiva muda nosso código.


Por que Alan Kay se arrependeu do nome “OOP”?

Alan Kay criou Smalltalk no Xerox PARC durante a década de 1970. O termo “programação orientada a objetos” veio dele.

Em 2003, quando um desenvolvedor perguntou por e-mail o que era OOP, ele respondeu:

“Eu me arrependo de ter usado a palavra ‘objeto’.

Isso fez as pessoas se concentrarem em um conceito menos importante. A grande ideia é ‘troca de mensagens’.”

Ao ler essa frase pela primeira vez, é normal estranhar. O que aprendemos como OOP sempre foi “como projetar bons objetos”.

Para Kay, o mais importante não estava dentro dos objetos. Era composto pelas relações e interações criadas quando eles trocam mensagens: essa é a essência do sistema.

Ele comparava programas a células biológicas. Cada célula esconde seu interior e se comunica apenas por sinais químicos, ou mensagens. A internet funciona da mesma forma: inúmeros computadores operam de modo independente e trocam apenas mensagens.


O que muda ao pensar com foco em mensagens?

“Chamar um método” e “enviar uma mensagem” parecem semelhantes, mas a perspectiva é diferente.

Uma chamada de método se aproxima de “execute esta função deste objeto”. Quem envia precisa conhecer um pouco do interior de quem recebe.

Já uma mensagem se aproxima de “processe isto; você decide como”. Quem envia quer apenas o resultado e não precisa saber como o outro lado processa a solicitação.

Veja um exemplo. O código delega o cálculo do desconto a cada objeto de nível de associação por meio de uma “mensagem”.

protocol Member {
    func discountedPrice(for price: Int) -> Int
}

struct Gold: Member {
    func discountedPrice(for price: Int) -> Int { price * 80 / 100 }
}
struct Silver: Member {
    func discountedPrice(for price: Int) -> Int { price * 90 / 100 }
}

// Quem envia não conhece nada sobre o cálculo de cada nível.
let members: [Member] = [Gold(), Silver()]
for m in members {
    print(m.discountedPrice(for: 10000))
}
// Saída: 8000
// Saída: 9000

O código chamador não contém if nem nomes de níveis.

Ele apenas envia a mensagem “calcule o preço com desconto”; cada objeto assume o cálculo. Mesmo com um novo nível, não é preciso alterar o chamador.

Esse é o poder da troca de mensagens descrito por Kay. O objetivo não é dividir objetos em partes menores, mas adotar uma forma de comunicação que reduz o acoplamento.

O chamador só precisa enviar uma mensagem; não precisa conhecer o nível
O chamador só precisa enviar uma mensagem; não precisa conhecer o nível

Então encapsulamento e polimorfismo são desnecessários?

Não. É justamente o contrário.

Quando você leva a troca de mensagens a sério, encapsulamento e polimorfismo surgem naturalmente.

Para se comunicarem apenas por mensagens, os objetos precisam ocultar seu estado interno. Isso é encapsulamento. Cada objeto reagir de forma diferente à mesma mensagem é polimorfismo.

Esses conceitos não são regras para decorar, mas resultados que surgem naturalmente ao projetar com foco em mensagens.

O problema está na ordem. Muitas pessoas começam com “vamos dividir bem as classes”. Surgem muitos objetos, mas eles enxergam o interior uns dos outros, gerando um código orientado a objetos apenas no nome.

A perspectiva de Kay inverte a ordem. Primeiro, pergunte: “A quais mensagens este objeto deve responder?”

Anotei esta pergunta antes do diagrama
Anotei esta pergunta antes do diagrama

Quando usar essa perspectiva e quando simplificar?

O design centrado em mensagens nem sempre é a resposta. O importante é usá-lo conforme a situação.

Situação Avaliação
Lógica de domínio com requisitos que mudam com frequência Uma estrutura de delegação centrada em mensagens é vantajosa
Fluxos complexos com muitos objetos colaborando Muito eficaz para reduzir o acoplamento
Scripts simples de transformação ou cálculo de dados Use funções em vez de envolvê-los desnecessariamente em objetos
Trechos em que o desempenho é extremamente importante Abstração excessiva pode virar um peso

Em resumo:

  • Quanto mais colaboração e mudanças houver, mais a perspectiva de mensagens se destaca.
  • Para uma lógica simples e fixa, é melhor manter tudo leve.
  • Lembre-se: o objetivo não é “dividir objetos”, mas “projetar a comunicação”.

É assim que perguntam em entrevistas

P. Qual é a essência da OOP segundo Alan Kay?

Não são os objetos em si, mas as mensagens trocadas entre eles. Kay comparou objetos a células que se comunicam de forma independente e considerou a troca de mensagens uma ideia maior que herança ou encapsulamento.

P. Quais benefícios práticos o design centrado em mensagens oferece?

O chamador não precisa conhecer a implementação interna do outro lado, então o acoplamento diminui. Assim, adicionar um novo tipo não exige alterar o chamador, tornando a estrutura mais resistente a mudanças.


Se OOP parece difícil, antes de desenhar um diagrama de classes pergunte: “O que esses objetos estão dizendo uns aos outros?”

Basta mudar uma perspectiva para sentir o código mais sólido. Bom design para você hoje!

Continue lendo