PHP e o Princípio da Responsabilidade Única

O primeiro dos cinco princípios que compõe o SOLID, um conjunto de boas práticas de design orientado a objetos de Robert Martin (Uncle Bob).

Alan Willms
Jul 5, 2015 · 3 min read

Uma classe só deveria ter um motivo para mudar — Uncle Bob

Segundo Bob, isso significa que uma classe só deveria ter um eixo de mudança. “Motivo para mudar”, “eixo de mudança”, esses termos não ajudam muito, não é?

Existe uma maneira mais fácil de pensar nisso: apenas leia a sua classe e escreva uma lista de tudo o que ela faz. Se a sua lista tiver mais do que um único item, quer dizer que a sua classe tem mais do que uma responsabilidade.

Exemplos em PHP

Neste primeiro exemplo temos uma classe “Pedido”, que implementa o padrão ActiveRecord. Não entrarei na discussão sobre o uso de ActiveRecord versus o uso de Repositórios segundo o Domain-Driven Design, então apenas assuma que a classe herda métodos para persistência de dados de sua classe-mãe.

Nessa classe encontramos vários motivos para mudança, ou várias responsabilidades:

  1. O método getCancelados() pode deixar de funcionar se o esquema, o adaptador ou o banco de dados em si mudar — esse método tem a responsabilidade de recuperar dados persistidos.
  2. O método getValorTotal() talvez seja alterado se a regra de negócio mudar, se um único item puder ser cancelado, ou o cálculo do desconto não for mais ou mesmo — a responsabilidade principal é calcular o valor total pedido.
  3. O método getValorTotalFormatado() pode mudar se introduzirem outros idiomas ou outras moedas, se optarem por usar tags HTML, ou mesmo se o cliente quiser outra forma de representação — esse método tem a responsabilidade de representar um valor monetário.

Desses métodos todos, percebemos que apenas um está relacionado à responsabilidade principal da classe. Os outros poderiam ser extraídos para outras classes. getCancelados() poderia ser um repositório ou uma classe de query; e getValorTotalFormatado() é responsabilidade da Visão da aplicação, desta forma sua lógica estaria em algum helper.

Mesmo que a classe tenha uma responsabilidade única, pode ser que um método tenha várias. Por exemplo:

Verificamos que o método acima tem três responsabilidades:

  1. Validar se o destinatário possui um endereço de e-mail válido;
  2. Acrescentar um rodapé à mensagem enviada;
  3. Enviar a mensagem.

Para resolver o problema, poderíamos extrair alguns métodos privados (como por exemplo para obter a mensagem completa) ou até mesmo classes inteiras (para validação de endereços de e-mails e um serviço para o envio).

Detectando Violações Automaticamente

Depois de conhecer esse princípio, sempre tomamos cuidado ao escrever novas classes e métodos, mas e quanto ao código legado? Existe uma maneira de varrer todo o repositório em busca de classes ou métodos com muitas responsabilidades?

Uma dica é utilizar um script de detecção de churn. Churn é a quantidade de vezes em que um arquivo é alterado ao longo do tempo, com base nos commits de um repositório. Se uma classe só deve ter um motivo para mudança, é possível que os arquivos mais alterados do seu repositório sejam de classes com mais de uma responsabilidade.

Outra opção é usar o popular PHPMD (PHP Mess Detector) para descobrir as classes e métodos que extrapolam uma determinada quantidade de linhas de código. Quanto maior o código, maior a possibilidade da classe ou método estar fazendo coisas demais, quebrando o princípio da responsabilidade única.

Essas ferramentas ajudam bastante, mas não confie cegamente nelas. Pode ser que você receba um falso positivo ou que alguma coisa simplesmente passe despercebida. Use sempre o bom senso.

Tableless

Um lugar para ler e discutir sobre desenvolvimento, design…

Alan Willms

Written by

Software development nerd. In 💙 with Ruby, PHP, JavaScript, Crystal, and other techy stuff.

Tableless

Tableless

Um lugar para ler e discutir sobre desenvolvimento, design, web semântica, back-end e outros assuntos relacionados a web. Se você quiser publicar artigos conosco, envie um email: medium[at]tableless.com.br ou *clique no link* http://bit.ly/escreva-tableless-medium

Alan Willms

Written by

Software development nerd. In 💙 with Ruby, PHP, JavaScript, Crystal, and other techy stuff.

Tableless

Tableless

Um lugar para ler e discutir sobre desenvolvimento, design, web semântica, back-end e outros assuntos relacionados a web. Se você quiser publicar artigos conosco, envie um email: medium[at]tableless.com.br ou *clique no link* http://bit.ly/escreva-tableless-medium

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store