Os princípios SOLID são uma rubrica testada pelo tempo para a criação de software de qualidade. Mas em um mundo de programação multiparadigma e computação em nuvem, eles ainda se comparam? Vou explorar o que significa SOLID (literal e figurativamente), explicar por que ainda faz sentido e compartilhar alguns exemplos de como pode ser adaptado para a computação moderna.
O que é SOLID?
SOLID é um conjunto de princípios destilados dos escritos de Robert C. Martin no início dos anos 2000. Foi proposto como uma forma de pensar especificamente sobre a qualidade da programação orientada a objetos (OO). Como um todo, os princípios SOLID apresentam argumentos sobre como o código deve ser dividido, quais partes devem ser internas ou expostas e como o código deve usar outro código. Vou mergulhar em cada letra abaixo e explicar seu significado original, bem como um significado expandido que pode ser aplicado fora da programação OO.
O que mudou?
No início dos anos 2000, Java e C ++ eram os reis. Certamente, em minhas aulas na universidade, Java era nossa linguagem de escolha e a maioria de nossos exercícios e aulas a usavam. A popularidade do Java gerou uma indústria artesanal de livros, conferências, cursos e outros materiais para levar as pessoas a escreverem códigos bons.
Desde então, as mudanças na indústria de software foram profundas. Alguns notáveis:
Linguagens com tipos dinâmicos , como Python, Ruby e especialmente JavaScript, tornaram-se tão populares quanto Java – ultrapassando-o em alguns setores e tipos de empresas.
Paradigmas não orientados a objetos , principalmente programação funcional (FP), também são mais comuns nessas novas linguagens. Até o próprio Java introduziu lambdas! Técnicas como metaprogramação (adição e alteração de métodos e recursos de objetos) também ganharam popularidade. Existem também sabores OO “mais suaves”, como Go, que possui tipagem estática, mas não possui herança. Tudo isso significa que classes e herança são menos importantes no software moderno do que no passado.
O software de código aberto proliferou. Considerando que antes a prática mais comum seria escrever software compilado de código fechado para ser usado pelos clientes, hoje em dia é muito mais comum que suas dependências sejam de código aberto. Por causa disso, o tipo de lógica e ocultação de dados que costumava ser imperativo ao escrever uma biblioteca não é mais tão importante.
Microsserviços e software como serviço explodiram em cena. Em vez de implantar um aplicativo como um grande executável que vincula todas as suas dependências, é muito mais comum implantar um pequeno serviço que se comunica com outros serviços, sejam seus ou fornecidos por terceiros.
Consideradas como um todo, muitas das coisas com que o SOLID realmente se importava – como classes e interfaces, ocultação de dados e polimorfismo – não são mais coisas com as quais os programadores lidam todos os dias.
O que não mudou?
O setor está diferente em muitos aspectos agora, mas há algumas coisas que não mudaram e provavelmente não mudarão. Esses incluem:
O código é escrito e modificado por pessoas. O código é escrito uma vez e lido muitas e muitas vezes. Sempre haverá a necessidade de um código bem documentado, particularmente APIs bem documentadas, sejam internas ou externas.
O código é organizado em módulos . Em alguns idiomas, são classes. Em outros, eles podem ser arquivos de origem individuais. Em JavaScript, eles podem ser objetos exportados. Independentemente disso, existe alguma maneira de separar e organizar o código em unidades distintas e delimitadas. Portanto, sempre haverá a necessidade de decidir a melhor forma de agrupar o código.
O código pode ser interno ou externo. Algum código é escrito para ser usado por você ou sua equipe. Outro código é escrito para ser usado por outras equipes ou mesmo por clientes externos (por meio de uma API). Isso significa que deve haver alguma maneira de decidir qual código está “visível” e o que está “oculto”.
SOLID “Moderno”
Nas seções a seguir, irei reafirmar cada um dos cinco princípios SOLID em uma declaração mais geral que pode ser aplicada à programação OO, FP ou multiparadigma e fornecer exemplos. Em muitos casos, esses princípios podem até mesmo se aplicar a serviços ou sistemas inteiros!
Observe que usarei o módulo de palavras nos parágrafos a seguir para me referir a um agrupamento de código. Pode ser uma classe, um módulo, um arquivo, etc.
Princípio de responsabilidade única
Definição original: “Nunca deve haver mais de um motivo para a mudança de classe.“
Se você escreve uma classe com muitas preocupações, ou “motivos para mudar”, então você precisa mudar o mesmo código sempre que qualquer uma dessas preocupações tiver que mudar. Isso aumenta a probabilidade de que uma alteração em um recurso interrompa acidentalmente um recurso diferente.
Por exemplo, aqui está uma classe Franken que nunca deve chegar à produção:
class Frankenclass {
public void saveUserDetails(User user) {
//…
}
public void performOrder(Order order) {
//…
}
public void shipItem(Item item, String address) {
// …
}
}
Nova definição: “Cada módulo deve fazer uma coisa e fazê-la bem.”
Este princípio está intimamente relacionado ao tópico de alta coesão . Essencialmente, seu código não deve misturar várias funções ou finalidades.
Aqui está uma versão FP deste mesmo exemplo usando JavaScript:
const saveUserDetails = (user) = { … }
const performOrder = (order) = { …}
const shipItem = (item, address) = { … }
export { saveUserDetails, performOrder, shipItem };
// calling code
import { saveUserDetails, performOrder, shipItem } from “allActions”;
Isso também pode se aplicar ao design de microsserviços; se você tem um único serviço que lida com todas essas três funções, ele está tentando fazer muito.
Princípio aberto-fechado
Definição original: “Entidades de software devem ser abertas para extensão, mas fech
.png)
.png)
.png)
.png)