Entenda os princípios S.O.L.I.D para melhorar a manutenção e escalabilidade do seu sistema
S.O.L.I.D. são 5 princípios da orientação a objetos que visam facilitar a manutenção e tornar seu sistema altamente escalável.
Seu acrônimo define os diferentes princípios, sendo eles:
SRP – Single Responsibility Principle – Princípio de responsabilidade única
OCP – Open Closed Principle – Princípio Aberto-Fechado
LSP – Liskov Substitution Principle – Princípio de Substituição de Liskov
ISP – Interface Segregation Principle – Princípio de Segregação de Interface
DIP – Dependency Inversion Principle – Princípio de Inversão de dependência
Iremos ver os principios em uma série de 5 posts, um para cada principio.
Single Responsibility Principle (SRP)
O Princípio de Responsabilidade única diz:
A component should have one, and only one, reason to change.
Um componente deve ter uma, e apenas uma razão para mudar.
Antes de começarmos a falar sobre o que ele quer dizer ou como implementamos uma solução que atenda ao princípio, vamos entender o que ele quer dizer com componente e o que seria uma razão para mudar.
Um componente: Um componente pode ser identificado como uma classe, um pacote e até mesmo um módulo.
Razão para mudar: A razão para mudar pode ser identificado como possíveis problemas ou grupos de problemas que implicaria na mudança de implementação do componente.
Ok! Agora que compreendemos melhor as palavras descritas no princípio, podemos seguir com sua explicação.
Um componente deve ter apenas uma razão para mudanças, isso é, deve ter apenas uma única responsabilidade, evitando “problemas” que não dizem respeito às suas funções.
Essas características podem ser alcançadas elaborando um componente que tenha alto grau de coesão e baixo grau de acoplamento. Veremos esses dois conceitos a seguir:
Coesão
Coesão no mundo de software diz respeito ao grau que várias partes de um componente se relaciona. Observe a seguinte implementação:
<?php class Quadrado { public function calcularArea() { ... } public function calcularPerimetro() { ... } public function desenhar() { ... } public function rotacionar() { ... } }
Nesse exemplo, nosso componente é a classe Quadrado que implementa 4 (quatro) métodos (partes):
- calcularArea: Responsável por calcular a área do quadrado;
- calcularPerimetro: Responsável por calcular o perimetro do quadrado;
- desenhar: Responsável desenhar o quadrado na tela; e
- rotacionar: Responsável por rotacionar a imagem do quadrado.
Agora vamos entender qual o grau de coesão entre as partes:
Os métodos calcularArea e calcularPerimetro estão intimamente relacionados entre si, pois são métodos responsáveis por realizar os cálculos do quadrado, portanto há uma alto nível de coesão entre eles
Os métodos desenhar e rotacionar estão intimamente relacionados entre si, pois são métodos responsáveis por lidar com a exibição do quadrado, portanto há uma alto nível de coesão entre eles.
Agora, se olharmos os métodos como um todo, os métodos desenhar e rotacionar não estão intimamente relacionados com os métodos calcularArea e calcularPerimetro, pois um lado é responsável por lidar com o cálculo, enquanto o outro com a exibição.
Podemos dizer então que o grau de coesão do componente é baixo, pois nem todas suas partes são fortemente relacionadas.
Essa implementação fere, também, o próprio princípio em si, pois a classe possui mais de uma razão para mudar: Em caso de alteração na forma de calcular E em caso de alteração na forma de exibir.
Para resolver esse problema, mudaremos a implementação para a seguinte forma:
<?php class QuadradoUI { public function desenhar(){ ... } public function rotacionar() { ... } } class Quadrado extends QuadradoUI { public function calcularArea(){ ... } public function calcularPerimetro(){ ... } }
Dessa forma, a classe Quadrado possui apenas os métodos relacionados ao cálculo, que são intimamente relacionados entre si, enquanto sua classe pai possui os métodos responsáveis apenas pela exibição, que são relacionados intimamente relacionados entre si.
Acoplamento
Acoplamento é o nível de interdependência entre vários componentes de software. Vamos ao exemplo prático:
<?php class Aluno { public function salvar() { ... $query = $this->obterQuery(); $this->conexao->exec($query); ... } public function obterIdEstudante() { ... } public function definirIdEstudante() { ... } }
Nesse exemplo temos um componente Aluno, com os seguintes métodos:
- salvar: Responsável por armazenar as informações no repositório de dados
- obterIdEstudante: Responsável por obter o id do estudante
- definirIdEstudante: Responsável por definir o id do estudante
A classe Aluno é responsável pelas operações básicas pelo aluno e também pelas operações com a base de dados, fazendo com que tenha dependência sobre o gerenciamento do banco de dados.
Essa manipulação do repositório do aluno fere a definição de baixo acoplamento, levando em consideração a alta dependência de operações de baixo nível sobre como armazenar as informações no repositório de dados.
Fere, também, o princípio SRP em sí, uma vez que há mais de uma razão para mudar, uma referente a alterações na abstração do aluno e outra relacionada às operações da base de dados.
Para resolver isso, vamos desacoplar a dependência das operações e colocá-las em outro componente, conforme o exemplo a seguir:
<?php class AlunoRepositorio { public function salvar($aluno) { ... $query = $this->obterQuery(); $this->conexao->exec($query); ... } } class Aluno { public function salvar() { $repositorio = new AlunoRepositorio(); $repositorio->salvar($this); } public function obterIdEstudante() { ... } public function definirIdEstudante() { ... } }
Dessa forma, o componente Aluno lida apenas com as operações básicas do aluno, enquanto as operações de baixo nível ficam responsáveis apenas pela classe AlunoRepositorio.
Perceba que ambos possuem apenas uma razão para mudar: Em caso de mudança na abstração do aluno, alteramos sua classe e em caso de mudança na manipulação de seu repositório, alteramos o AlunoRepositorio.
E com isso concluimos o primeiro artigo sobre os principios do S.O.L.I.D.
About author
Você pode gostar também
Desvendando o Zend Framework 3: O guia definitivo para desenvolvedores PHP
Se você está lendo este artigo provavelmente você já desenvolveu ou pretende desenvolver algum projeto de software. Talvez você nunca tenha usado um framework mesmo que não o Zend antes
Descubra o poder do Node.js e como ele pode transformar seu desenvolvimento web
Afinal, o que é o Node.js ? O Node.js ou apenas “Node” é um interpretador de javascript assíncrono, de código aberto e orientado a eventos criando pelo programador Ryan
Gerando Dados Aleatórios com Paralelização no Shell: Guia Prático
Gerar dados aleatórios com paralelização no shell. Falando assim parece até alguma coisa muito importante ou difícil, mas vamos entender sua utilidade na prática. Vez ou outra preciso de uma