Reflexões sobre SOLID - Princípios Básicos
Tags: solidprinciples, programming, learning, designpatterns
Published: 2024-05-02 17:59:47

Recentemente, tenho refletido bastante sobre alguns padrões de desenvolvimento, boas práticas e qualidade de código. Diversas ideias vêm à mente com um tema tão abrangente, mas nesta série de artigos, gostaria de explorar especificamente o padrão de design que hoje conhecemos como "SOLID", acrescentando algumas visões pessoais sobre sua filosofia, suas implementações concretas, e sobre cada letra que o compõe.

---

## Neste artigo

[Sobre suas origens](#sobre-suas-origens)
[Sobre sua importância](#sobre-sua-importância)
[Sobre sua definição](#sobre-sua-definição)
[Sobre sua aplicabilidade](#sobre-sua-aplicabilidade)
[Reflexões finais](#reflexões-finais)
[Textos complementares](#textos-complementares)

---

## Sobre suas origens

![Sobre suas origens](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pculc3meamjvf6s060dm.png)

Inicialmente propostos por Robert C. Martin em seu artigo "_Design Principles and Design Patterns_" de 2000, e posteriormente expandido por Michael Feathers para enclausurá-los no acrônimo que conhecemos hoje, os princípios SOLID foram cimentados no âmbito da Engenharia de Software como **padrões essenciais para construção de software robusto, de fácil manutenção e escalável**.

Esse é o resumo como conhecemos hoje, mais de 20 anos depois de sua concepção. É interessante vermos como, atualmente, essa visão atinge exatamente aquilo que toda pessoa engenheira de software, assim como qualquer corporação com ativos tecnológicos, busca como resultado: **robustez, mantenabilidade, escalabilidade e qualidade**.

Talvez por conta disso, SOLID acabou tornando-se uma "_buzzword_" nos últimos anos - ou seja, uma nomenclatura de fácil memorização, onde tanto aqueles que a posicionam como parte de seu conhecimento, quanto os que exigem essa competência para vagas de desenvolvimento, não necessariamente entendem ou pregam sua real aplicabilidade.

Isso não significa que sua base seja descartável, muito pelo contrário. Na verdade, o que acontece é que, vivendo na era de ouro do conteúdo, muitos focam em saber **o que** é, através de breves explosões de informação, mas nem todos se aprofundam no detalhe essencial de **como funciona**.

---

## Sobre sua importância

![Sobre sua importância](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cqxaafr8s2go8aitjorc.png)

Quando falamos sobre SOLID (ou qualquer outro padrão arquitetural), é importante entendermos que são **propostas para melhorarmos nosso trabalho** na construção de software. Ou seja, não é algo que você instala em seu produto, uma dependência que você precisa acrescentar na aplicação, e muito menos algo que automaticamente criará um software competente e resolverá todos os problemas existentes e futuros. Os melhores ingredientes e panelas, quando entregues a alguém que não sabe cozinhar, não garante um alimento de qualidade.

Gostaria de destacar uma frase que, para mim, resume muito bem o porquê a adoção de tais propostas e padrões são uma constante em nossa área. Por mais que Martin esteja se direcionando a um tema mais específico em seu artigo no trecho abaixo (_design patterns_), creio que se aplica aos _design principles_ de forma similar:

> A definição essencial de um padrão de design é uma boa solução, bem estabelecida e conhecida, para um problema comum.
>
> -- <cite>Robert C. Martin</cite>

Ou seja, tais paradigmas de desenvolvimento têm suas raízes em **otimizar o processso de repetição**. Ao longo de nossas carreiras, nos encontramos diversas vezes perante problemas em que o compartilhamento de código e ideias acaba apresentando-se naturalmente nas implementações. Duplicamos abordagens, consultamos construções anteriores para nos basearmos para as novas, e assim acabamos por evoluir o código de forma pouco consistente.

Graças aos exercícios de otimização realizados por grandes pensadores e pela comunidade dessa área ao longo dos anos, assim como ocorre com experimentações científicas, **bases sólidas** começam a surgir, servindo como pontos de partida para a solução de novos problemas. Blocos de códigos que antes eram duplicados agora são transformados em padrões que evitam tais duplicidades, propondo em seu lugar formas de **distribuir lógicas de forma reaproveitável**.

---

## Sobre sua definição

![Sobre sua definição](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x3jzs3jl58ebbmdk4kb7.png)

É nesse ponto que os princípios SOLID se encaixam: **como ferramentas multifacetadas** para resolver problemas e criar padrões que, conceitualmente, podem ser compartilhados entre membros da equipe, atuais ou futuros (considerando que todos busquem ratear esse conhecimento).

O acrônimo em si identifica os 5 princípios, não necessariamente em ordem de importância, mas na ordem para formar a palavra solid (_sólido_, em português), criando todo o vínculo criativo com o conceito de robustez:

- **S**ingle Responsibility Principle: _Princípio da Responsabilidade Única_ - Classes devem ter somente uma responsabilidade, e portanto, um único motivo para mudar;
- **O**pen/Closed Principle: _Princípio do Aberto/Fechado_ - Classes devem ser fechadas para modificação, mas abertas para estensões;
- **L**iskov Substitution Principle - _Princípio de Substituição de Liskov_ - Classes devem ser facilmente substituíveis por suas subclasses;
- **I**nterface Segretation Principle - _Princípio da Segregação de Interface_ - É melhor ter múltiplas interfaces específicas do que uma única interface genérica.;
- **D**ependency Inversion Principle - _Princípio da Inversão de Dependência_ - Classes devem depender de interfaces e abstrações, e não de implementações concretas.

Lendo somente o descritivo de cada letra, fica claro o porquê de tantas pessoas sentirem pouca confiança, ou muita confusão, nesse tópico. Digo isso por experiência: sem exemplos concretos ou demonstrações práticas, fica difícil compreender o que é "depender de abstrações e não de implementações", ou até mesmo por qual motivo você precisaria "substituir uma subclasse" sem entender o devido contexto. O artigo original de Martin inclui constantemente exemplos, por mais abstratos que sejam, visto que é realmente um tema que pode passar despercebido se não conseguirmos visualizá-lo.

Um ponto interessante é que todos os conceitos abordam o tema de **classes**, exceto a letra **I**, que é o único que abrange a visão de **interfaces**. Ou seja, o nascimento do SOLID (e dos _design patterns_ intrinsicamente ligados à sua filosofia), estão amarrados ao paradigma de OOP (Object-Oriented Programming, ou _Programação Orientada a Objeto_). É importante considerar o momento em que o artigo de Martin foi publicado, o que nos leva a pensar sobre a maturidade deste padrão e de sua longevidade naquele momento da história.

Isso não significa que os princípios SOLID sejam limitados somente a essa forma de implementação, pelo menos a nível de código. Outros modelos de desenvolvimento, como FP (Functional Programming - _Programação Funcional_), também podem beber da mesma fonte na questão de ideologia. O que quero dizer é que as ideias propostas, de termos criticidade na visão analítica sobre interfaces e entidades, podem fazer sentido também em outros contextos no qual lidaremos com essas iterações. Pretendo me aprofundar nessa ideia em partes futuras dessa série.

---

## Sobre sua aplicabilidade

Ao entender as definições, podemos nos perguntar (eu, pelo menos, me perguntei na primeira vez): "Certo, isso tudo é muito interessante, mas e na prática? Como aplico esses conceitos no meu dia-a-dia? Como encontro oportunidades nos meus projetos para exercitar esses conhecimentos?". Em meio a isso, existe um perigoso impulso que pode surgir, e é mais do que imprescindível reforçamos uma breve realidade: **talvez você não precisará usar todas as letras, ao mesmo tempo, nem o tempo inteiro**. 

Os princípios SOLID, assim como qualquer padrão de design ou arquitetural, são um pouco mais empíricos do que outras áreas de conhecimento, exigindo que antes exercitemos nossa **visão analítica** do que somente o conhecimento técnico. Muitos problemas já conhecidos podem ser resolvidos de uma forma elegante, garantida e bem estabelecida - mas será que o problema que você possui se encaixa nessa solução? Ou você está buscando problemas para exercitar um ensaio de engenharia de software?

Com base nas minhas turbulentas primeiras experiências com esses paradigmas, consegui abstrair 3 pontos de partida que podem auxiliar no entendimento e facilitar a real aplicação da visão conceitual:

1. **Entender a essência abstraída**: Antes de observar um código ou um exemplo prático, tente entender o que cada letra significa e o que ela propõe **a nível de design, não de código**. Ou seja, independentemente da linguagem ou _framework_ em uso, quais os ganhos a nível da estrutura da aplicação? E as perdas? O próprio artigo de Martin é um excelente ponto de partida, mas como mencionei anteriormente, conteúdos online com linguagens mais informais (ou formais, conforme sua preferência) é o que menos falta em nossa era.

2. **Exercitar exemplos da sua realidade**: De nada adiantará se os exemplos que você buscar fugirem muito dos seus conhecimentos concretos. Por mais reais que eles possam ser, é possível que eles não sejam condizentes com a sua realidade pessoal. Pessoalmente, tive bastante contato com _FinTechs_ e projetos para chão de fábrica, e pensar em entidades relacionadas nesses contextos me ajuda bastante. E claro, **pense em sistemas** - o funcionamento de uma biblioteca municipal é algo bastante universal, por exemplo. Você pode até mesmo se basear em _hobbies_ pessoais, visualizar algo que você gosta e domina e enxergá-lo com esse olhar analítico (quando penso em videogames, não consigo contar quantas vezes utilizei _Super Mario 64_, _Banjo-Kazooie_ e _Donkey Kong 64_ como chaves de leitura).

3. **Buscar uma visão analítica**: Comece a observar, no seu dia-a-dia, as entidades com as quais você trabalha, por mais simples que seu projeto seja. Será que ele já está otimizado o suficiente? Você consegue enxergar duplicidade de código ou de implementações? Existe algo que poderia ser mais genérico, ou talvez mais específico? Tome alguns minutos do seu dia para fazer essa reflexão e realmente busque entender o sistema por trás do produto - faça anotações, diagramas, um breve descritivo, e busque os relacionamentos. Não é fácil, e não é uma competência que surgirá da noite para o dia, mas o ideal é começar por algum lugar. Recomendo alternar também entre realizar essa atividade de forma singular e com uma pessoa parceira - analisar em equipe pode trazer _insights_ que talvez passassem despercebidos, visto que cada pessoa terá seu próprio discernimento com base em sua bagagem de experiência.

---

## Reflexões finais

![Reflexões finais](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oirld7t1bun8e2oizyoi.png)

Os princípios SOLID compõe um ferramental extremamente poderoso que, se utilizado da forma correta e ponderada, pode trazer diversos benefícios tanto ao software construído quanto àquele que o construiu. Não é a toa que, mesmo décadas depois da ideia original de Robert C. Martin ter sido publicada, continuamos falando sobre, pregando, ensinando e compartilhando ideias sobre o tema. A longevidade de todo o conceito, inclusive o fato de estar sofrendo iterações e evoluções por parte da comunidade, demonstra sua importância determinística.

Existem muitas pessoas que conseguem apresentar o SOLID de forma muito mais elegante, ou mais extravagante, do que eu. Minha ideia com esse artigo foi ruminar um pouco sobre o tema, e apresentar algumas ideias da minha filosofia sobre esse paradigma. :)

Obrigado por ter lido até aqui. Em futuras iterações desta série, quero me aprofundar um pouco mais em cada uma das letras, com alguns exemplos práticos e novamente refletindo sobre o tema.

---

## Textos complementares

**Design principles and design patterns**, artigo de Robert C. Martin, 2000. Consultado em https://staff.cs.utu.fi/~jounsmed/doos_06/material/DesignPrinciplesAndPatterns.pdf

**Design Patterns**, livro referenciado por Martin como GOF (Gang of Four). Detalhamento sobre o livro pode ser encontrado na Wikipedia. Consultado em https://en.wikipedia.org/wiki/Design_Patterns