Software

20 abr, 2023

O que é SOLID?

Publicidade

SOLID é um acrônimo que representa cinco princípios no design de softwares orientados a objetos, sendo:

Single Responsability
Open-Closed
Liskov Substitution
Interface Segregation
Dependency Inversion Principle

Embora Go não seja uma linguagem orientada a objetos, ainda assim conseguimos utilizar os princípios de SOLID. Abaixo, vamos ver com mais detalhes cada um dos princípios.

Single Responsability

Uma classe ou, como é no caso do Go, uma struct deve ter uma única responsabilidade. Ou seja, cada struct deve ser projetada para executar uma determinada ação.

Pensando em um CRUD, é claro que você não terá uma struct para cada uma das ações (Create, Read, Update e Delete). Mas também não terá somente uma struct para lidar com todas as responsabilidades do package.

O ideal é ter pelo menos uma struct que represente a entidade do package. Uma para lidar com as transações com banco de dados, comumente chamada de repository. E outra para tratar as requests, independente se forem via API ou em algum modelo MVC.

Open-Closed

Uma classe deve estar aberta para extensões, mas fechada para modificações. Ou seja, sempre que for necessário adicionar funcionalidades, devemos estender a classe ao invés de modificá-la.

Embora seja possível através da estratégia de embedding, esse princípio é um pouco mais difícil de ser aplicado em Go.

Isso por que, diferente de uma linguagem que implementa orientação a objetos, em Go, nem tudo estará atrelado a uma struct.

Mesmo assim, para um maior reaproveitamento das funções do sistema, é importante que elas tenham suas responsabilidades muito bem definidas.

Liskov Substitution

Classes “filhas” podem ser utilizadas no lugar das classes “pais” sem que o programa quebre.

Esse é outro princípio que, para ser aplicado ao Go, talvez exija algumas mudanças que em outras linguagens, como, por exemplo, o PHP, não é necessário.

Como Go é uma linguagem fortemente tipada, não é possível passar struct do tipo Bar, onde só é aceito structs do tipo Foo.

Outro ponto que vale lembra é que, em Go, não existe o conceito de herança. Logo, mesmo que uma struct utilize-se da estratégia de embedding, ela não tem relação direta com a outra struct como acontece na herança de classe.

Interface Segregation

Uma classe não deve ser obrigada a implementar interfaces e métodos que não utilizará. Em outras palavras, é melhor ter 6 interfaces bem específicas, do que 2 mais genéricas.

Esse princípio, inclusive, é amplamente aplicado no core da linguagem Go. Se olharmos para o package io, temos, por exemplo, as interfaces:

  • io.Reader
  • io.Writer
  • io.ReadWriter

Onde a terceira nada mais é do que um embedding das duas primeiras.

Dependency Inversion Principle

Dependências devem ser abstraídas, para que os módulos de alto nível não dependam dos módulos de baixo nível.

  • ATENÇÃO! Dependency Inversion e Dependency Injection são coisas distintas.

Uma forma de implementar esse conceito, é utilizar interfaces para definir atributos de structs e parâmetros de funções. Assim, ao invés de esperar um tipo concreto, ou seja, altamente acoplado, esperamos qualquer tipo que implemente a interface.

Conclusão

Embora não seja possível aplicar todos os conceitos de SOLID em Go da mesma forma que em linguagens orientadas a objetos, ainda assim podemos construir softwares altamente escaláveis e robustos.

No meu ponto de vista, os conceitos que não conseguimos aplicar parcial ou integralmente, não trazem impacto nos quesitos robustez, escalabilidade e flexibilidade do software.

Em um próximo post, vou trazer exemplo de código escrito em Go para cobrir cada um dos pontos aqui explicados.

Por isso, se você ainda não é assinante, não deixe de assinar nossa newsletter. É gratuita e seus dados não serão vendidos para anunciantes.

Até a próxima!

 

*O conteúdo deste artigo é de responsabilidade do(a) autor(a) e não reflete necessariamente a opinião do iMasters.