Princípio do Aberto/Fechado (OCP)
Definição
O Princípio do Aberto/Fechado (Open/Closed Principle - OCP) afirma que módulos, classes ou funções devem estar abertos para extensão, mas fechados para modificação.
Isso significa que um componente pode receber novos comportamentos sem que seu código existente precise ser alterado — geralmente por meio de herança, composição ou uso de interfaces.
Esse é o segundo princípio do SOLID, um conjunto de boas práticas para design orientado a objetos.
Por que é importante
Ao seguir o OCP, torna-se possível evoluir um sistema sem quebrar funcionalidades existentes. Isso reduz o risco de introduzir bugs em código já validado e favorece a manutenção contínua com menor impacto em módulos antigos.
Também promove a extensibilidade do sistema: novas regras, casos de uso ou variações podem ser implementadas de forma controlada e previsível.
Exemplo prático (Python)
Este código viola o OCP porque exige que a função
calcular_desconto
seja modificada toda vez que um novo tipo
de produto com desconto for adicionado:
def calcular_desconto(produto):
if produto.tipo == "livro":
return produto.preco * 0.9
elif produto.tipo == "curso":
return produto.preco * 0.8
# outros casos exigiriam mais elifs aqui
O problema aqui não é técnico — o código funciona. A questão é estrutural: toda vez que surge uma nova regra de negócio, como um desconto para "assinaturas", você precisa editar diretamente uma função existente. Isso traz vários riscos:
- Reabrir código já testado pode introduzir bugs acidentais
- Responsabilidades se acumulam em uma única função
- Fica difícil isolar, testar ou reutilizar regras específicas
- A função se torna um ponto único de crescimento e fragilidade
Para aplicar o OCP, podemos isolar cada regra de desconto em sua própria classe, usando composição ou polimorfismo:
class RegraDeDesconto:
def calcular(self, produto):
return produto.preco
class DescontoLivro(RegraDeDesconto):
def calcular(self, produto):
return produto.preco * 0.9
class DescontoCurso(RegraDeDesconto):
def calcular(self, produto):
return produto.preco * 0.8
Agora, se surgir uma nova regra, como DescontoAssinatura
,
podemos adicioná-la como uma nova classe
sem alterar nada do que já foi escrito e validado. Isso
mantém o sistema:
- Aberto para extensão (você pode incluir novas funcionalidades)
- Fechado para modificação (nenhuma lógica existente precisa ser alterada)
Essa abordagem reduz riscos, melhora a organização e segue o espírito do OCP.