Skip to content

Reboredo.bit

Menu
  • Início
  • Sobre mim
  • Posts
Menu
singleresponsibility2

Princípio da Responsabilidade Única e as implicações na Orientação a Objetos e Arquitetura de Software

Posted on 25 de novembro de 202526 de novembro de 2025 by victoreboredo.dev@gmail.com

O paradigma orientado a objetos é amplamente difundido no mundo de desenvolvimento de software. Através dele conseguimos simular de maneira eficiente as modularidades de um processo no mundo real, com reaproveitamento de código e aplicando métodos e padrões que tornam o código manutenível, eficiente e mais limpo e direto. Para isso, devemos ter maturidade para conseguir aplicar corretamente a responsabilidade de algo a seu devido layer. É aqui que entra esse tópico fundamental.


Coesão

Dentre os diversos conceitos aplicados na Orientação a Objetos, um ótimo conceito para se aprofundar é a coesão. A coesão é um princípio extremamente útil na programação (mesmo se utilizamos outro paradigma ao programar, como o estruturado, por exemplo). Através da coesão conseguimos organizar o código de maneira a deixá-lo mais limpo e esteticamente bem estruturado.

Em seu livro “Orientação a Objetos: Aprenda seus conceitos e suas aplicabilidades de forma efetiva”, o professor Thiago Leite e Carvalho define coesão como um conceito que:

“[…] preconiza que cada unidade de código deve ser responsável somente por possuir informações e executar tarefas que dizem respeito somente ao conceito que ela pretende representar.”

Podemos aplicar a coesão através das classes e dos relacionamentos associativos das mesmas. Criar unidades de código coesas com classes e associações contribui para definição de blocos de códigos responsáveis somente por tarefas e conceitos às quais elas se propõem. (Thiago Leite e Carvalho, pg. 23)

Classes coesas são extremamente importantes em sistemas orientados a objetos. São mais fáceis de dar manutenção, são compostas por menos códigos e podem ser mais facilmente reutilizadas no software. Elas também são menos propensas a defeitos e bugs.

Single Responsability Principle

O SRP ou também Princípio da Responsabilidade Única é o primeiro pilar do solid e existe para que possamos aplicar a coesão no nosso código.
Ele nada mais é do que a parte prática de tudo o que vimos até aqui, portanto colocamos em prática a coesão através do SRP. Ele preconiza que:

Uma classe deve ter uma, e apenas uma, razão para mudar.

É um tanto complexo no dia a dia do programador, termos bem definido um grupo de regras que irão de certa forma definir o conceito de uma classe coesa e de uma classe não-coesa. Os conceitos que podem rodear isso acabam por ser subjetivos. Acredito que o principal a se verificar em uma análise de classe é quantos métodos diferentes ela tem/quão grande elas são e quantos comportamentos diferentes é possível encontrar nela. Quanto mais métodos, código e comportamentos uma classe tiver, mais ela se tornará uma candidata ao título de “Classe não-coesa”.

Exemplo

Neste exemplo, criarei a classe User. Ela será responsável por salvar um usuário em meu sistema, validar o e-mail e enviar um e-mail de boas-vindas para o usuário.

class User {
  constructor(public name: string, public email: string) {}

  saveToDatabase() {
    console.log(`Saving user ${this.name} to the database...`);
  }

  sendWelcomeEmail() {
    console.log(`Sending welcome email to ${this.email}...`);
  }

  validateEmail() {
    console.log(`Validating email ${this.email}...`);
    return this.email.includes("@");
  }
}

const user = new User("John Doe", "john.doe@example.com");

if (user.validateEmail()) {
  user.saveToDatabase();
  user.sendWelcomeEmail();
}

Nossa classe está totalmente errada! Ela tem 3 tarefas totalmente distintas a que deveriam ser independentes. Se alguma lógica de validação do e-mail ou do banco de dados mudar, teremos que modificar a classe inteira, que deveria apenas representar a entidade Usuário. Criar testes unitários para testar a classe se torna uma dor de cabeça, já que devemos ter teste para cada método com lógicas distintas.

Aplicando o SRP…

class User {
  constructor(public name: string, public email: string) {}
}
class UserRepository {
  save(user: User) {
    console.log(`Saving user ${user.name} to the database...`);
  }
}
class EmailService {
  sendWelcomeEmail(user: User) {
    console.log(`Sending welcome email to ${user.email}...`);
  }
}
class UserValidator {
  validateEmail(user: User): boolean {
    console.log(`Validating email ${user.email}...`);
    return user.email.includes("@");
  }
}
const user = new User("John Doe", "john.doe@example.com");
const validator = new UserValidator();
const repository = new UserRepository();
const emailService = new EmailService();
if (validator.validateEmail(user)) {
  repository.save(user);
  emailService.sendWelcomeEmail(user);
}

Agora, cada classe tem uma única responsabilidade. User apenas modela a entidade, UserRepository lida com o armazenamento no banco de dados, EmailService cuida do envio de emails, e UserValidator se concentra na validação.

Desta maneira podemos modularizar melhor qualquer mudança/dependência nas validações, isto é, se a validação mudar basta mudar um local do código. Se for necessário incluir mais campos na entidade de usuário e incluir uma validação para este novo campo, toda a edição no código ficará mais fácil!

Aplicando SRP em outras frentes

Um ponto importantíssimo no mundo de Software é a arquitetura que aplicamos. Pensando nesse princípio, um padrão arquitetural que vem à minha mente é o MVC (Model - View - Controller).

Esse modelo de software segrega as responsabilidades de um software monolítico em 3 frentes:

  • Model: É o domínio de nossa regra de negócio. São classes que representam tabelas de banco de dados ou entidades bem definidas. Através delas podemos gerenciar repositório de dados, fazer consultas e manipular dados.
  • View: É a camada que define a parte de interface de usuário da aplicação. Nela estarão os elementos gráficos interativos onde o cliente irá requisitar, manipular e deletar dados. É a parte de front.
  • Controller: É a camada responsável por ligar o "core" do software ao cliente (usuário, seja via app mobile, desktop ou web). Ele pode capturar uma requisição – seja via REST, GraphQL, gRPC e muitos outros – e converter tudo isso em uma ação dentro da aplicação.

Existem no mercado diversos frameworks/libs que utilizam o MVC como arquitetura, os principais e mais completos – na minha opinião, é claro – são: Laravel (PHP), Express (JavaScript), ASP.Net Core MVC (C#), Spring (Java) e Django (Python).

Conclusão

O Princípio da Responsabilidade Única é muito mais do que uma regra teórica: é uma prática essencial para quem busca escrever um código orientado a objetos robusto e escalável. Ao aplicar o SRP, garantimos que nossas classes se mantenham coesas, focadas em uma única responsabilidade, o que facilita a manutenção, testes e futura evolução do sistema.

A coesão, como discutido, é um dos pilares para alcançar da boa arquitetura de software. Quando uma classe possui uma única responsabilidade, ela se torna mais fácil de entender, de modificar e de estender, permitindo que o código evolua de maneira mais natural conforme as necessidades do projeto mudam. Além disso, a aplicação do SRP reduz a chance de bugs, pois minimiza o impacto das mudanças ao isolar responsabilidades.

Adotar o SRP desde o início de um projeto pode parecer um desafio, mas os benefícios a longo prazo superam em muito o esforço inicial. Projetar classes pequenas e bem definidas contribui para a criação de um sistema modular, onde cada parte pode ser desenvolvida, testada e mantida independentemente. Isso não apenas melhora a qualidade do código, mas também promove uma maior colaboração entre equipes de desenvolvimento, permitindo que diferentes partes do sistema evoluam em paralelo sem interferências indesejadas.

Em suma, o SRP não é apenas um princípio de design, mas uma prática que influencia diretamente a qualidade e a sustentabilidade do software que desenvolvemos. Incorporá-lo em nossa abordagem à programação orientada a objetos é um passo fundamental para construir sistemas que sejam não apenas funcionais, mas também fáceis de manter e adaptar ao longo do tempo.

Bibliografia

  • Solid — S.R.P — Single Responsibility Principle
  • SOLID – Single Responsability Principle
  • (S): Aplicando o “Princípio da Responsabilidade Única” com Typescript e Java

Navegação de Post

← (D): Aplicando o “Princípio da Inversão de Dependências” com Typescript e Java
5 Pilares financeiros que destacam negócios de alto valor →

Deixe um comentário Cancelar resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Recent Posts

  • Microsserviços: 5 Lições Aprendidas — Um Olhar Arquitetural
  • 5 Pilares financeiros que destacam negócios de alto valor
  • Princípio da Responsabilidade Única e as implicações na Orientação a Objetos e Arquitetura de Software
  • (D): Aplicando o “Princípio da Inversão de Dependências” com Typescript e Java
  • (I): Aplicando o “Princípio da Segregação da Interface” com Typescript e Java

Archives

  • novembro 2025

Categories

  • Empreendimento (1)
  • Engenharia (9)
  • Finança (2)
  • Java (6)
  • Liderança (1)
  • Orientação a Objetos (8)
  • Programação (9)
  • Programação Estruturada (2)
  • Typescript (8)
© 2025 Reboredo.bit | Powered by Minimalist Blog WordPress Theme