SOLID em React: Princípio do Aberto/Fechado (OCP)

Vinicios Neves
5 min readJun 8, 2023

E aí, galera! Seguindo com a nossa série sobre os princípios SOLID no React, hoje vamos embarcar no mundo do Princípio do Aberto/Fechado, ou Open/Closed Principle (OCP) em inglês.

A gente pode imaginar o OCP como um personagem de Transformers. Sim, esses robôs incríveis que são mais do que os olhos podem ver! Nossos amigos Autobots e Decepticons são carros, aviões, ou tanques que podem se transformar em robôs gigantes, certo? Pois então, eles têm uma estrutura básica (o modo robô ou o modo veículo), que não muda, mas têm a capacidade de se estender, se transformar, para se adaptar a diferentes situações.

Pensando em software, a ideia é a mesma. O Princípio do Aberto/Fechado afirma que “Entidades de software (classes, módulos, funções etc.) devem ser abertas para extensão, mas fechadas para modificação”. Traduzindo: uma vez que você desenvolveu e testou uma entidade de software, ela deve permanecer a mesma, assim como um Transformer no modo carro. Se precisarmos alterar o comportamento dela, devemos estender a entidade, assim como um Transformer muda para o modo robô, e não modificá-la.

E por que isso é importante? Esse princípio é crucial para garantir a manutenibilidade do software, evitando que mudanças desnecessárias quebrem partes do código que já estavam funcionando.

Agora, vamos ver como isso funciona na prática com o React!

Exemplo que não segue o OCP

Imagine que temos um componente Input bem simples em nossa aplicação. Ele recebe tudo via props: label, value, onChange, required, disabled, e assim por diante. Parece uma solução prática, não é mesmo?

const Input = ({ label, value, onChange, required, disabled }) => {
return (
<div>
<label>{label}</label>
<input
type="text"
value={value}
onChange={onChange}
required={required}
disabled={disabled}
/>
</div>
);
}

Agora, recebemos uma nova feature: precisamos adicionar um ícone dentro do nosso Input. E aí? Vamos ter que modificar nosso componente para incluir essa nova funcionalidade. E a cada nova feature, o componente fica mais inchado e mais difícil de manter. Está evidente que essa abordagem viola o Princípio do Aberto/Fechado.

Agora, refatorando para uma nova abordagem

Para resolver essa situação, vamos modificar nosso componente Input para seguir o Princípio do Aberto/Fechado. Vamos utilizar a estratégia de composição, criando um FormField que contém um Label, um IconInput e o próprio TextInput.

const FormField = ({ children }) => {
return <div>{children}</div>;
}

const Label = ({ children }) => {
return <label>{children}</label>;
}

const TextInput = ({ value, onChange, required, disabled }) => {
return (
<input
type="text"
value={value}
onChange={onChange}
required={required}
disabled={disabled}
/>
);
}

const IconInput = ({ icon, children }) => {
return (
<div>
<i className={`icon-${icon}`} />
{children}
</div>
);
}

Agora, quando precisamos incluir um ícone em nosso Input, não precisamos modificar nenhum dos componentes existentes. Basta criar um novo componente IconInput e usá-lo onde for necessário. Assim, nosso código fica mais limpo e mais fácil de manter:

<FormField>
<Label>Nome</Label>
<IconInput icon="user">
<TextInput value={name} onChange={handleNameChange} required />
</IconInput>
</FormField>

Conclusão

E aí, o que achou dessa jornada pelo Princípio Aberto/Fechado? É fascinante, não é mesmo? No entanto, é bom lembrar que, apesar de ser uma ferramenta poderosa para tomada de decisões, o OCP não é uma bala de prata que vai resolver todos os seus problemas de projeto. Cada princípio SOLID tem seu lugar e seu momento para ser usado.

Isso dito, não podemos negar que conhecer esses princípios pode nos dar uma visão mais clara sobre como estruturar nosso código de forma mais eficiente e sustentável. Se quiser se aprofundar ainda mais nesse assunto, os livros “Clean Architecture” do Tio Bob e “Implementing Domain-Driven Design” do Vaughn Vernon são ótimas escolhas. São leituras densas, mas valiosas para quem está em busca de excelência na arte de codificar.

No próximo artigo, vamos mergulhar no Princípio da Responsabilidade Única (SRP). Sim, você não leu errado: estamos indo de trás pra frente na sequência dos princípios SOLID. Mas quem disse que seguir a ordem é sempre a melhor maneira de aprender? Até lá!

P.S. E aí, curtiu esse artigo sobre o OCP e React? Mas antes de terminar, se liga nesse PS:

Então vamos falar um pouquinho mais sobre a estratégia de composição na criação de componentes, que eu acho que pode ter sido feita meio en passant.

Sabe aquele quebra-cabeças que você montava quando era criança? Cada peça individual tem a sua própria forma e cor, e por si só não representa muita coisa. Mas quando você junta todas as peças, forma-se uma imagem bem maneira, não é mesmo? A composição de componentes no React funciona de forma semelhante.

Em vez de criar um único componente monolítico que tenta fazer tudo, nós criamos componentes menores e mais focados, que fazem apenas uma coisa (e fazem bem feito, diga-se de passagem). Em seguida, nós “encaixamos” esses componentes menores para criar um componente maior e mais complexo.

E aí, se você é fera em Orientação a Objetos, deve estar se perguntando “Pô, mas isso não é a tal da composição em OO?” E eu te respondo: exato! O que é muito louco porque mostra como conceitos que parecem tão distintos podem se interseccionar.

P.S. do P.S. Ah, sabe essa expressão “en passant” que usei ali em cima? Se você ainda não a conhece, talvez esteja se perguntando o que significa. Então, “en passant” é uma expressão em francês que significa “de passagem” e é usada para indicar que algo foi mencionado casualmente, sem dar muita ênfase. Não resisti a fazer um P.S. do P.S., desculpa ae. Mas se você chegou até aqui, pode ter ganhado uma dica de francês de brinde né!

Fala sério, tá valendo muito a pena ler esse artigo! :)

--

--