Desvendando o SOLID: Open/closed Principle

Vitor Ferraz Varela
3 min readApr 2, 2021

--

Introdução

No último artigo dessa série sobre desvendando o SOLID, falamos sobre o SRP (Single Responsibility Principle) e de que forma está relacionado com a coesão do nosso código. Se você não ainda teve a oportunidade de ler, recomendo fortemente que de uma olhada antes de continuar.

Hoje vamos falar sobre o princípio do aberto e fechado (OCP — Open/closed Principle), que é ser extremamente importante mas difícil de se dominar.

O princípio do OCP

No artigo sobre o SRP entendemos que, para buscar coesão do nosso código devem separar as responsabilidades em classes menores e que devemos buscar um acompanhamentos com classes que sejam estáveis, ou seja, que mudam pouco.

Outro ponto interessante sobre a busca da coesão é ter classes que evoluam de uma forma mais fácil e do princípio do “Aberto e fechado” tem como objetivo trabalhar diretamente com a manutenção e evolução das classes.

Na sua definição formal diz:

“Você deve ser capaz de estender um comportamento de uma classe sem a necessidade de modificá-lo.”

Isso bem importante pois queremos ser capazes de adicionar novas funcionalidades, ou seja, abertas para extensão, sem ter que ficar alterando ou modificando nosso código o tempo todo, ou seja, fechadas para alteração.

Classes extensíveis

O princípio do aberto e fechado se relaciona muito com a forma que escrever programação orientada a objetos (OOP). Envolve lidar com acoplamento, coesão, pensando em abstrações para nossos problemas.

Quando se tem uma boa abstração, é fácil evoluir sua aplicação. Evoluir nossa aplicação com abstrações previamente pensadas, acaba sendo uma evolução muito mais orgânica do nosso código, além disso evita ficar colocando ifs espalhados por todo o código, sem necessidade.

A ideia não é abolir os ifs do nosso código, muitas vezes um simples if resolve o problema. Portanto, seja parcimonioso.

Por isso, que esse é um princípio fácil de se entender mas difícil de se dominar, pois nem sempre pensamos nas abstrações que estamos criando e de que forma elas afetam nosso código.

Um exemplo na prática

Para entender um pouco mais como esse exemplo funciona na prática, vamos ter como base o seguinte cenário: Possuímos uma classe de um jogo, cuja responsabilidade é recuperar uma lista de usuários de uma API, converte de JSON para uma classe de modelo e retorna o resultado. Um exemplo bem convencional e comum no nosso dia a dia.

Agora nosso jogo ganhou uma nova expansão, além de ter usuários normais também podemos jogar como alienígenas e nossa classe UserFetcher deve ser capaz de buscar os tipos de classes.

Uma alternativa para resolver esse problema poderia ser copiar todo o código da UserFetcher e mudar o tipo de retorno de User para Alien. Mas se existir novos tipos no futuro? Vamos ter que ficar copiando e colando para todo tipo novo que aparece? Na verdade. isso acaba sendo bem pouco produtivo.

Bom, vamos tentar entender de que forma podemos abstrair essa busca para algo genérico. Nesse caso, nossos objetos de modelos podemos conformar com o protocolo Decodable e assim não precisamos depender de um tipo específico para realizar a busca e conversão.

Essa nova implementação acabou ficando muito próxima da original, porém agora não dependemos mais de um tipo específico para realizar a buscar e sim um objeto genérico que conforme o protocolo de Decodable, que é usado para converter um JSON para um objeto.

Por fim, para utilizar basta usar da seguinte forma:

typealias UserFetcher = Fetcher<User>

typealias AlienFetcher = Fetcher<Alien>

No futuro caso tenha necessidade de buscar um tipo, só será necessário que esse novo objeto conforme com o protocolo `Decodable` que é algo mais genérico e faz parte da nossa abstração e criar mais uma linha como por exemplo:

typealias DogFetcher = Fetcher<Dog>

Conclusão

Seguimos dando sequência na nossa serie de artigos do desvendando o SOLID, no primeiro artigo falamos sobre o princípio da responsabilidade única e de que forma isso se relaciona com a coesão das classes, se ainda não viu confira aqui.

Hoje, discutimos as vantagens de termos classes que são abertas para extensão e fechadas para modificação. Também começamos a notar que alguns conceitos começam a se entrelaçar: acoplamento, abstrações , coesão e estabilidades das classes.

Muito obrigado por acompanhar até aqui e me siga no Medium para não perder os próximos artigos.

Vocês podem me encontrar nas redes sociais:

Linkedin | Instagram | Twitter

--

--