Divisão de classes

Vocês já ouviram falar do SRP (Single Responsability Principle)? Trata-se de um dos princípios incentivados pelo SOLID, que prega a responsabilidade única de classes e métodos. Apesar de já conhecermos a importância deste princípio, o artigo de hoje visa realçar a relevância da divisão de classes na arquitetura de um projeto, prezando pela alta coesão. Acompanhe!

Introdução

Criar classes com responsabilidades bem definidas é um dos pontos fortes do Clean Code e o principal propósito do SRP (Princípio da Responsabilidade Única).

Muitas vezes, ao desenvolver um software, algumas classes podem apresentar uma sobrecarga de responsabilidades, ou seja, fazer mais do que inicialmente foi projetada para exercer. Embora o motivo possa ser uma falha de abstração, essa situação também pode surgir através de constantes modificações no projeto ou refatorações arbitrárias.

A divisão de classes é uma técnica que consiste em identificar pontos no código que podem ser “desacoplados” de uma classe, buscando reduzir ou evitar responsabilidades excessivas e, evidentemente, trazendo coesão para a arquitetura de um projeto.

Um breve cenário

Bom, chega de enrolação e vamos partir para um exemplo prático!

O código abaixo faz uma operação bem básica: obtém os valores que estão em cada campo de texto e os atribuem em diferentes variáveis. Por fim, estes valores passam por uma validação. Se estiverem válidos, os dados são gravados, caso contrário, uma mensagem de aviso é exibida.

No entanto, observe que 6 parâmetros são passados para a função ValidarDados e também para o método GravarDados. Essa quantidade de parâmetros, além de comprometer a objetividade do código, também dificulta a interpretação do método como um todo. Claro, o método acima é apenas uma demonstração, mas, imagine que, em um caso real, existam 20 variáveis referentes aos dados do cliente, implicando que teríamos que passar 20 parâmetros na função. O que acha?

Seguindo a mesma diretriz, suponha que um desenvolvedor irá utilizar a função ValidarDados em outra parte do código. Ao se deparar com a declaração da função, provavelmente a impressão inicial do desenvolvedor será: “Nossa, tenho que declarar 20 variáveis para passar como parâmetros para este método?”. Se você fosse este desenvolvedor, ficaria perplexo, não?

Oras, basta criar variáveis de classe!
Boa ideia! Se criarmos variáveis de classe, não será preciso declará-las dentro do método e, portanto, não será necessário passar parâmetros, já que essas variáveis estarão visíveis no escopo global da classe.

Bom, então vamos implementar essa ideia:

Mas espere aí… ainda não me convenci da solução. Criamos 6 variáveis que estarão visíveis para todos os métodos da classe, mas apenas 2 destes métodos irão utilizá-las. Isso indica um certo “egoísmo” destes 2 métodos, não? Em uma analogia, é o mesmo que enviar um e-mail para 30 pessoas, porém, o conteúdo só interessar a 2 delas.

Alguém provavelmente irá contestar: “Sua analogia está errada! No caso do e-mail, basta eu selecionar as 2 pessoas que se interessam pelo conteúdo e enviar a mensagem somente para elas.”. Certo, e por que não podemos aplicar este mesmo pensamento no nosso código? A analogia está certa, o que está errado é a nossa implementação! 🙂

A Divisão de Classes na prática

Finalmente chegamos no âmago do artigo. Se existem apenas 2 métodos que utilizam as variáveis de classe que criamos, a recomendação é extrair estes métodos para uma classe separada, junto com as variáveis que eles utilizam. Essa é a divisão de classes citada no título deste artigo.

Ao realizarmos essa extração, definiremos adequadamente a responsabilidade de cada classe, reduzindo a baixa coesão. Além disso, as variáveis (que tanto nos preocupa) serão removidas do escopo global, como se estivéssemos removendo aquele conteúdo indesejado enviado para os outros 28 destinatários do e-mail.

Uma sugestão é criar uma nova classe (chamada TCliente, por exemplo) e transformar as variáveis em propriedades dessa classe. Os dois métodos, ValidarDados e GravarDados serão públicos e, então, poderão ser chamados a partir de outras classes:

Finalmente, veremos como ficou a solução:

Bem melhor, não é? Separamos as responsabilidades, aumentamos a coesão e melhoramos a arquitetura do programa.
O exemplo deste artigo é mais uma prova das vantagens que a Orientação a Objetos, Clean Code e SOLID podem nos proporcionar no desenvolvimento de um software. Assim que possível, pretendo elaborar mais artigos como este!

 

Abraço e até a próxima!


André Celestino