Open/closed principle (OCP) – Principio aberto/fechado

Salve, salve galera, continuando nossa conversa sobre os princípios SOLID vamos falar agora sobre o princípio aberto/fechado. Esse certamente se trata de um dos menos conhecidos.

Esse princípio diz que:

Entidades de software (classes, módulos, funções, etc) devem estar abertas para extensão, mas fechadas para modificação.

E ae ? o que isso quer dizer ?

Quer dizer que nossas classes devem estar aptas para serem extendidas mas fechadas para mudanças.

Uma das práticas do dia-a-dia mais utilizadas se trata de podermos extender uma classe para adicionarmos funcionalidades nela sem que as funcionalidades já implementadas sejam impactadas.

Falou, falou, falou e não entendi nada ! Cade o exemplo ???

Vamos la galera, imaginem que tenhamos uma classe Pessoa, que possui um método Salvar que recebe como parâmetros um enumerador que informa o tipo de pessoa (Física ou Jurídica) e o nome da pessoa (deixemos de lado qualquer outro principio ou metodologia,  OK ?). Agora imaginem que esse enumerador determina em qual tabela os dados serão salvos, como ficaria a implementação disso ? Teríamos algo semelhante ao seguinte (essa se trata de uma forma, OK ?)


public enum TipoPessoa
 {
      Fisica,
      Juridica
 }

 public class Pessoa
 {
    public void Salvar(TipoPessoa tipoPessoa, string nome)
    {
        //Poderiamos usar o switch mas nao vem ao caso
        if (tipoPessoa == TipoPessoa.Fisica)
        {
            //regra para salvar na tabela 1
        }
        if (tipoPessoa == TipoPessoa.Juridica)
        {
             //regra para salvar na tabel 2
        }
    }
 }

Muitos vão se identificar e falar “eu faria isso !” . Acontece que aqui temos um problema muito grande que se trata da complexidade de manutenção que esses IFs estão gerando , além claro que, caso coloquemos no ar um tipo de “pessoa novo” que possua algum problema (entenda-se BUG) ,afetaríamos toda a classe. Imaginaram o tamanho que vai ficar esse código se tivermos 20 tipos diferentes ?

Mas e ae ? Como podemos fazer ?

Atendendo a ao princípio podemos fazer a implementação da seguinte forma (apenas uma sugestão ).


 public abstract class Pessoa
 {
      public abstract void Salvar(string nome);
 }

 public class PessoaFisica : Pessoa
 {
      public override void Salvar(string nome)
      {
          //regras
      }
 }

 public class PessoaJuridica : Pessoa
 {
     public override void Salvar(string nome)
     {
          //regras
     }
 }

 public class PessoaOutroTipo : Pessoa
 {
        public override void Salvar(string nome)
        {
           //regras
        }
 }

Reparem que estamos utilizando abstrações para chegar no resultado.

Tudo bem , mas cade a explicação ?

Todos os softwares evoluem (não me diga…..), e a forma de garantir essa evolução sem problemas , pode ser fazendo com que as entidades estejam fechadas para modificação (percebam que a classe Pessoa não sofre modificações e podemos fazer sub-implementações dela para atender cada cenário, sem que um interfira no outro) e aberta para extensões (Fisica, Juridica, ETC).

Com isso obtemos um maior controle na manutenção. Além claro de manter o primeiro princípio que vimos, o SRP, uma vez que, apenas iremos modificar a classe devido a sua responsabilidade única.

Pessoal espero que tenha ficado claro o uso e a função desse principio.

Att.