DEV Community

Cover image for Entendendo SOLID de uma vez por todas | Parte 01 - (SRP)
Rafael Honório
Rafael Honório

Posted on • Edited on

Entendendo SOLID de uma vez por todas | Parte 01 - (SRP)

Motivação

Este é o primeiro texto de uma série onde explicarei, de maneira clara e lúdica, cada um dos conceitos do SOLID. Em vez de replicar conteúdos já disponíveis pela internet, pretendo fazer um dump das minhas experiências pessoais e do meu entendimento sobre o tema. Hoje, iniciaremos com o princípio SRP (Single Responsibility Principle).

Breve resumo

Os conceitos que formam o acrônimo SOLID já são bem conhecidos há pelo menos 20 anos e são frequentemente abordados em entrevistas técnicas. Mais do que isso, entender profundamente cada princípio melhorará significativamente a qualidade do seu código. A intenção destes textos é esclarecer definitivamente cada conceito para que você consiga aplicá-los independentemente da linguagem que utilizar.

Obs.: No final do texto, vou deixar dois repositórios com exemplos práticos implementando cada conceito em Elixir e Golang, contudo, o mais importante é compreender o fundamento para que você consiga adaptá-lo à sua realidade.

SRP - Single Responsibility Principle

Esse termo foi cunhado por Robert Martin (Uncle Bob) em 2000, no livro Design Principles and Design Patterns. Porém, esse é um problema clássico da programação, que surgiu após os anos 80 com o aumento da complexidade das aplicações. Com a complexidade crescendo, tornou-se necessário organizar melhor o código, o que impulsionou a implementação de POO no mercado, visto que já existia pelo menos há 20 anos na década de 80/90.

Segundo o livro Clean Code, o conceito de SRP pode ser resumido da seguinte maneira:

"Uma classe ou módulo deve ter um, e apenas um, motivo para mudar." (Clean Code, pág. 138)

Mas, afinal, o que isso significa? Dentro de uma estrutura, seja ela um módulo, pacote ou classe, qualquer interação que fuja da sua responsabilidade original provavelmente violará o SRP.

Veja estes dois exemplos:

  • Situação 01: Dentro de uma estrutura de usuário, existem propriedades e métodos que devem sempre refletir ações e características diretamente relacionadas ao usuário. Exemplo:
type User struct {
    Name     string
    Age      int
    Document string
    // outras propriedades
}

// Em Go, este trecho "(u *User)" indica que esta função é um método da struct User.

func (u *User) IsAdult() bool {
    // lógica aqui
}

func (u *User) ValidateDocument(document string) bool {
    // lógica aqui
}

Enter fullscreen mode Exit fullscreen mode

Porém, se adicionarmos algo como:

func (u *User) SaveUser() {
    // lógica aqui
}

Enter fullscreen mode Exit fullscreen mode

Claramente estaremos quebrando o SRP, já que salvar o usuário não deveria ser responsabilidade direta da estrutura de domínio User.

  • Situação 02: Também é possível violar esse princípio em outras camadas da aplicação. Veja o exemplo abaixo em Elixir:

# Código com violação do SRP

defmodule User do // define o módulo
  def create_user(attrs) do // define a função
    user =
      %User{attrs}
      |> Repo.insert!() // insere no banco de dados
    Email.send_welcome(user) // envia email para o cliente 
    Logger.info("User created: \#{user.id}") // loga a ação
    user // retorna o usuário
  end
end

# Código seguindo o SRP

defmodule UserCreator do
  def create(attrs) do
    Repo.insert!(%UserStruct{attrs})
  end
end

defmodule WelcomeNotifier do
  def send_welcome_email(user) do
    Email.send_welcome(user)
  end
end

Enter fullscreen mode Exit fullscreen mode

Neste exemplo em Elixir, fica claro como é fácil misturar responsabilidades. No código inicial, temos criação de usuário, envio de e-mail e log em uma única função, o que fere o SRP. O código corrigido separa claramente as responsabilidades.

Com esses exemplos, fica mais fácil entender como devemos pensar ao escrever código. Lembre-se de sempre avaliar se cada componente possui apenas uma única razão para mudar, caso haja mais de uma, com certeza o princípio SRP está quebrado nesse contexto.

Repositórios com exemplos práticos:

Se ainda houver dúvidas ou se você discordar de algo, deixe um comentário, até mais!

Top comments (0)