Ao longo da minha jornada como desenvolvedor — principalmente vindo do desenvolvimento web — sempre ouvi falar sobre SOLID. Mas foi entrando de vez no desenvolvimento mobile que esses princípios começaram a fazer um sentido muito maior no meu dia a dia.
SOLID não é um conjunto de regras rígidas, e sim um guia de boas práticas para construir sistemas mais limpos, flexíveis e fáceis de manter.
E, para explicar isso, vou usar analogias simples e exemplos reais em Java, mostrando como cada princípio se aplica no código.
Vamos direto ao ponto.
🧱 O que é SOLID?
SOLID é um acrônimo formado por cinco princípios fundamentais da programação orientada a objetos:
- S — Single Responsibility Principle
- O — Open/Closed Principle
- L — Liskov Substitution Principle
- I — Interface Segregation Principle
- D — Dependency Inversion Principle
A ideia central é simples: projetar software que seja fácil de entender, evoluir, testar e manter.
Agora, vamos ver cada princípio na prática.
1️⃣ Single Responsibility Principle (Responsabilidade Única)
“Uma classe deve ter apenas um motivo para mudar.”
Imagine uma classe que salva usuários e também envia e-mails.
Ela faz duas coisas — e isso é um problema.
❌ Exemplo que viola o SRP
public class UserService {
public void saveUser(User user) {
// salva no banco
}
public void sendWelcomeEmail(User user) {
// envia e-mail
}
}
Se qualquer parte falhar (e-mail, banco, regra de negócio), a classe inteira é afetada.
✔️ Exemplo seguindo o SRP
public class UserRepository {
public void save(User user) {
// salva no banco
}
}
public class EmailService {
public void sendWelcomeEmail(User user) {
// envia e-mail
}
}
Cada classe tem sua responsabilidade, e o código fica muito mais claro e testável.
2️⃣ Open/Closed Principle (Aberto para Extensão, Fechado para Modificação)
“Você deve poder adicionar novos comportamentos sem alterar código existente.”
✔️ Exemplo com descontos
public interface Discount {
double apply(double price);
}
public class NoDiscount implements Discount {
public double apply(double price) {
return price;
}
}
public class BlackFridayDiscount implements Discount {
public double apply(double price) {
return price * 0.5;
}
}
Precisa de um novo tipo de desconto?
Crie uma nova classe.
Nenhuma linha das anteriores precisa mudar.
Isso é Open/Closed na prática.
3️⃣ Liskov Substitution Principle (Substituição de Liskov)
“Subclasses devem poder substituir suas classes base sem quebrar o comportamento esperado.”
❌ Exemplo que quebra o princípio
public class Bird {
public void fly() {
System.out.println("Voando...");
}
}
public class Penguin extends Bird {
@Override
public void fly() {
throw new UnsupportedOperationException("Pinguins não voam!");
}
}
O contrato promete que todo pássaro voa, mas o pinguim não.
Isso quebra o comportamento esperado.
✔️ Exemplo correto
Separando o que pode voar do que não pode:
public interface Bird {
void eat();
}
public interface FlyingBird extends Bird {
void fly();
}
public class Eagle implements FlyingBird {
public void eat() {}
public void fly() {}
}
public class Penguin implements Bird {
public void eat() {}
}
Agora, tudo faz sentido.
4️⃣ Interface Segregation Principle (Segregação de Interfaces)
“Nenhuma classe deve ser forçada a implementar métodos que não usa.”
❌ Exemplo errado
public interface Worker {
void work();
void eat();
}
public class Robot implements Worker {
public void work() {}
public void eat() {
// robô não come...
}
}
O robô é obrigado a implementar algo que não faz sentido para ele.
✔️ Exemplo correto
public interface Workable {
void work();
}
public interface Eatable {
void eat();
}
public class Robot implements Workable {
public void work() {}
}
public class Human implements Workable, Eatable {
public void work() {}
public void eat() {}
}
Interfaces menores = classes mais limpas.
5️⃣ Dependency Inversion Principle (Inversão de Dependência)
“Dependa de abstrações, não de implementações concretas.”
❌ Exemplo errado
public class MySQLDatabase {
public void connect() {}
}
public class UserService {
private MySQLDatabase database = new MySQLDatabase();
public void save(User user) {
database.connect();
}
}
O serviço está acoplado ao MySQL.
Se quiser trocar para Postgres, precisa alterar o código.
✔️ Exemplo correto
public interface Database {
void connect();
}
public class MySQLDatabase implements Database {
public void connect() {}
}
public class PostgresDatabase implements Database {
public void connect() {}
}
public class UserService {
private Database database;
public UserService(Database database) {
this.database = database;
}
public void save(User user) {
database.connect();
}
}
Agora, trocar o banco é só configurar outra implementação.
🎯 Conclusão
SOLID não é sobre “seguir regras”, e sim sobre facilitar sua vida como desenvolvedor.
Quanto mais seu sistema cresce, mais esses princípios fazem diferença.
Eles ajudam a criar:
- código mais limpo,
- classes mais coesas,
- responsabilidades claras,
- menos bugs,
- mais testes,
- e mais flexibilidade para evoluir o projeto.
Se você está trabalhando com Android, KMP ou qualquer arquitetura moderna (como MVVM), SOLID é um aliado poderoso.
Top comments (0)