O documento descreve o Princípio Aberto/Fechado (OCP), que estabelece que entidades devem poder ser estendidas sem serem modificadas. O OCP encoraja adicionar novo código ao invés de modificar o existente, facilitando a manutenção. Ele é aplicado usando classes abstratas e subclasses concretas, permitindo estender o comportamento sem alterar o código original.
OCP - The Open Close Principle - Princípio aberto/fechado
1. OCP - The Open Close Principle (Princípio aberto/fechado)
“As entidades devem estar abertas para extensão, mas fechadas para modificação” (Martin, p. 99)
Este princípio encoraja os desenvolvedores a adicionar novo código a cada refatoração, ao invés de
mudar o código existente. Esta é uma ideia interessante, pois sugere manutenção fácil, já que o
desenvolvedor não tem que se preocupar em alterar o código existente. Deixando de lado por um
momento o quão realístico ou imaginável possa ser este princípio, vamos ver como o OCP deve ser
aplicado, começando pela explicação de seus dois atributos básicos:
● “Aberto para extensão”: é possível estender o comportamento do módulo, à medida que os seus
requisitos mudam.
● “Fechado para modificação”: estender este comportamento não quer dizer mudar o código-fonte
do módulo.
À primeira vista, estes atributos parecem opostos, mas a implementação deste princípio é feita
graças à utilização de classes abstratas e subclasses concretas, com delegação de todo ou parte do
algoritmo às subclasses (padrão Strategy). Usando este procedimento, é possível estender ou mudar o
comportamento da classe abstrata, através da criação de novas subclasses que implementam uma nova
versão de um método da classe abstrata.
Uma vez que o ambiente ágil requer um código apto a receber modificações, mas ao mesmo tempo
que obedeça à definição de pronto dentro de uma time box, este é um dos princípios mais valiosos.
Obedecê-lo faz com que o código não seja mudado, e sim estendido, o que demanda menos esforço por
parte do desenvolvedor.
O OCP tem sido usado de duas formas. Ambas utilizam herança para a implementação, mas os
objetivos, resultados e técnicas são diferentes:
● “Meyer’s OCP”: O termo e Open Close Principle é atribuído a Bertrand Meyer (1988). Esta vertente
do OCP diz que a implementação de uma classe só pode modificada para se corrigir erros. No caso
de novos recursos ou mudanças nos requisitos, uma nova classe deve ser criada. Esta nova classe
deve reutilizar o código da superclasse através de herança. As subclasses podem ou não ter a
mesma interface da superclasse. É a chamada implementação por herança .
● “Polymorphic OCP”: nos anos 90, o OCP foi redefinido para abranger o uso de classes abstratas,
onde as implementações podem ser mudadas e múltiplas implementações podem ser criadas e
polimorficamente substituídas. Diferentemente da vertente de Meyer, a implementação por
polimorfismo defende a herança através de classes abstratas. As especificações de interface podem
ser herdadas, mas não necessariamente a implementação. Assim, a interface já existente é fechada
para modificações e novas implementações devem, no mínimo, contemplar uma interface.
2. Aplicação prática (implementação em diagramas de classe):
Analisando primeiramente o contra-exemplo (diagrama inicial), percebemos
que a classe concreta Produto é associada à classe Venda e possui os métodos
FormaDePagamento e OpcaoDeCompra. Se uma nova forma de pagamento for
criada, bem como uma opção de compra, é preciso que os padrões de projeto sejam
obedecidos, evitando-se IFs/Switches. Então, como fazer?
Através do princípio aberto-fechado, as classes foram estendidas, criando-se duas interfaces
(FormasDePagamento e OpcoesDeCompra), cada qual com suas possibilidades atuais (cartão de crédito,
débito online, mensal e anual) A implementação passa a ser para interface. Internet e TV a cabo, por sua
vez, deixam de ser pertencer à classe Venda e passam a ter uma relação de herança com a classe Produto
que, por sua vez, é uma classe abstrata.
Diagrama final alterado:
Usar OCP é satisfazer a condição de contrato único para uma classe. Já que esta deve ter uma e
somente uma responsabilidade, só deverá ser modificada se esta responsabilidade mudar. Como
desenvolvedores, sabemos que o seu comportamento inevitavelmente irá mudar. É esta a proposta do
OCP: manter a estabilidade (contrato da classe), criando pontos de extensão.