DEV Community

Cover image for [PT-BR] Granularidade: A Arte de Quebrar o Sistema no Tamanho Certo
Márcio Renan
Márcio Renan

Posted on • Edited on

[PT-BR] Granularidade: A Arte de Quebrar o Sistema no Tamanho Certo

Projetar um sistema orientado a objetos vai muito além de simplesmente criar classes e distribuir métodos. Uma das decisões mais difíceis e também mais cruciais está em como quebrar o sistema em partes menores, ou seja, como decompor o domínio em objetos e responsabilidades bem definidas.

Essa tarefa envolve diversas variáveis: encapsulamento, acoplamento, coesão, performance, reusabilidade e flexibilidade. No centro disso tudo está um conceito que, embora pouco discutido diretamente, tem um impacto profundo na qualidade da arquitetura: granularidade.


O que é granularidade na orientação a objetos?

Granularidade, no contexto da programação orientada a objetos, representa o nível de divisão ou fragmentação de um sistema em seus componentes — especialmente em classes e objetos.

É como decidir se uma classe deve fazer várias coisas ou uma coisa só.

Alta vs. Baixa granularidade

  • Alta granularidade:
    Classes pequenas e especializadas, cada uma com uma responsabilidade bem definida.

    • Exemplo: EmailFormatter, EmailSender, EmailLogger.
  • Baixa granularidade:
    Classes grandes e genéricas, que agrupam múltiplas responsabilidades.

    • Exemplo: EmailService que formata, envia, registra e trata erros.

Ambas as abordagens são válidas dependendo do contexto, mas ignorar essa decisão tende a gerar:

  • Classes deus (God classes) que fazem tudo,
  • Ou um excesso de microcomponentes difíceis de entender e manter.

Uma analogia simples

Pense em granularidade como o tamanho das peças de um quebra-cabeça:

  • Peças grandes (baixa granularidade) são fáceis de manusear e montam a imagem rapidamente, mas oferecem menos precisão.
  • Peças pequenas (alta granularidade) oferecem mais detalhe e flexibilidade, mas exigem mais tempo e atenção para montar.

No design OO, sua tarefa é encontrar o tamanho certo das peças para montar o sistema com clareza, coerência e equilíbrio.

O perigo dos extremos

  • Granularidade baixa demais pode levar a sistemas monolíticos e difíceis de manter.
  • Granularidade alta demais pode gerar sistemas superfracionados, com alta complexidade de coordenação.

Portanto, granularidade não é sobre "mais ou menos classes", mas sim sobre classes do tamanho certo para o contexto certo.


Por que granularidade importa no design de software?

Decidir o nível adequado de granularidade impacta diretamente na qualidade, manutenibilidade e evolução do sistema. Um projeto bem estruturado em termos de granularidade tende a ser mais:

  • Coeso: cada classe tem uma responsabilidade clara.
  • Desacoplado: componentes se comunicam por contratos bem definidos.
  • Fácil de testar: unidades pequenas são mais fáceis de isolar.
  • Reutilizável: componentes especializados podem ser reaproveitados em outros contextos.
  • Escalável e evolutivo: alterações em uma parte do sistema causam menos impacto nas demais.

Relação com princípios SOLID

A granularidade está intimamente ligada a diversos princípios do design orientado a objetos, como:

  • SRP (Single Responsibility Principle): quanto mais granular for uma classe, maior a chance de ela ter uma única responsabilidade bem definida.
  • OCP (Open/Closed Principle): classes menores e específicas tendem a ser mais fáceis de estender sem modificar.
  • DIP (Dependency Inversion Principle): componentes bem definidos e coesos facilitam a abstração de dependências.

Negligenciar a granularidade pode fazer com que esses princípios sejam quebrados, resultando em código rígido, frágil e difícil de evoluir.


Exemplos práticos de granularidade

Exemplo com baixa granularidade (Classe Deus)

public class OrderService {
    public void createOrder(Order order) {
        validateOrder(order);
        calculateTotal(order);
        saveToDatabase(order);
        sendConfirmationEmail(order);
        logOrder(order);
    }

    // múltiplos métodos de diferentes responsabilidades
}
Enter fullscreen mode Exit fullscreen mode

Esse exemplo concentra várias responsabilidades em uma única classe: validação, cálculo, persistência, comunicação e logging.

Refatorado com granularidade mais adequada

public class OrderService {
    private final OrderValidator validator;
    private final OrderCalculator calculator;
    private final OrderRepository repository;
    private final EmailSender emailSender;
    private final OrderLogger logger;

    public void createOrder(Order order) {
        validator.validate(order);
        calculator.calculate(order);
        repository.save(order);
        emailSender.send(order);
        logger.log(order);
    }
}
Enter fullscreen mode Exit fullscreen mode

Agora, cada responsabilidade está em uma classe separada, especializada e com alta coesão. O OrderService atua como orquestrador dessas ações.

Resultado:

✔️ Mais legível

✔️ Mais testável

✔️ Mais flexível

✔️ Menos propenso a efeitos colaterais


Como encontrar o equilíbrio certo?

Granularidade não é algo fixo — depende do contexto. Mas há algumas boas práticas que ajudam a guiar suas decisões:

Dicas para equilibrar granularidade

  1. Comece simples e evolua com o tempo
    • Não superdivida prematuramente. Refatore quando a classe estiver assumindo múltiplas responsabilidades.
  2. Use o SRP como bússola
    • Sempre pergunte: essa classe faz mais de uma coisa? Se sim, pode ser hora de dividir.
  3. Evite abstrações desnecessárias
    • Criar classes apenas por criar (ex: Manager, Handler, Helper) pode gerar complexidade sem ganho real.
  4. Observe sinais de má granularidade
    • Métodos enormes, nomes genéricos, dificuldade em testar ou reaproveitar podem indicar baixa granularidade.
  5. Prefira granularidade que favoreça reutilização e manutenção
    • Componentes pequenos e coesos são mais fáceis de entender e adaptar.

Conclusão

Granularidade é uma daquelas decisões arquiteturais que não costumam ganhar destaque mas fazem toda a diferença na qualidade de um sistema orientado a objetos.

Ao entender como dividir seu sistema no "tamanho certo", você constrói software mais limpo, flexível e sustentável.

Nem tudo precisa ser micro, e nem tudo precisa ser monolítico: o segredo está em encontrar o equilíbrio ideal para o seu contexto.

Reflita: como estão as classes do seu projeto hoje? Estão grandes demais? Ou fragmentadas além da conta?

Top comments (0)