Object Calisthenics: Pare de Usar Getters e Setters (Parte 1)

·2 min de leitura

O que é Object Calisthenics?

Object Calisthenics é um conjunto de exercícios/regras propostos por Jeff Bay (no livro The ThoughtWorks Anthology) para treinar design OO, forçando limites para revelar melhor modelagem.

Não é dogma: é ginástica. Use como experimento.

Depois de SOLID: DIP, essa série complementa com hábitos micro que mudam macro.

“Pare de usar getters e setters” — o que isso quer dizer?

Não é “a linguagem ‘obriga’ um estilo então vamos gerar getter/setter por hábito”.

A crítica é a anemia: objetos que são sacos de dados + código procedural que os manipula por fora.

Exemplo ruim: objeto anêmico

<?php

declare(strict_types=1);

final class Money
{
    public function __construct(private int $cents) {}

    public function cents(): int
    {
        return $this->cents;
    }

    public function setCents(int $cents): void
    {
        $this->cents = $cents;
    }
}

final class Checkout
{
    public function applyDiscount(Money $total, int $percent): void
    {
        $new = (int) ($total->cents() * (1 - $percent / 100));
        $total->setCents($new);
    }
}

Explicação: Checkout conhece como centavos são armazenados e alterados. A invariante (não negativo, arredondamento) fica espalhada.

Melhor: comportamento no lugar certo

<?php

declare(strict_types=1);

final readonly class Money
{
    public function __construct(private int $cents)
    {
        if ($this->cents < 0) {
            throw new InvalidArgumentException('Money não pode ser negativo.');
        }
    }

    public function applyPercentDiscount(int $percent): self
    {
        $new = (int) ($this->cents * (1 - $percent / 100));

        return new self($new);
    }
}

Explicação: não expomos setter; expomos operação com invariante. readonly ajuda a impedir mutação acidental quando a linguagem oferece esse recurso.

Quando getters ainda fazem sentido?

Leituras pontuais para apresentação (DTO, view model) existem, a ideia é não transformar domínio em struct com acessores infinitos.

Conclusão

Menos getters/setters “por hábito” → mais comportamento coeso e menos procedural escondido.

Referências

  • Bay, J. Object Calisthenics (capítulo em The ThoughtWorks Anthology).
  • Evans, E. Domain-Driven Design (rich domain model).

Links