Princípios que todo developer deve conhecer
O que eles têm em comum?
Você pode fazer assim...
public class GeradorExtrato {
public void emitirExtrato(String tipo) {
if (tipo.equals("SimplificadoMensal")) {
// TODO...
} else if (tipo.equals("SimplificadoQuinzenal")) {
// TODO...
} else if (tipo.equals("SimplificadoSemanal")) {
// TODO...
} else if (tipo.equals("Completo")) {
// TODO...
}
}
}
...ou...
Substituindo condicional por polimorfismo com Enum
public enum TipoExtrato {
public abstract void processarExtrato();
SimplificadoMensal {
public void processarExtrato() {
// TODO ...
}
},
SimplificadoQuinzenal {
public void processarExtrato() {
// TODO ...
}
},
SimplificadoSemanal {
public void processarExtrato() {
// TODO ...
}
},
Completo {
public void processarExtrato() {
// TODO ...
}
};
}
public class GeradorExtrato {
public void emitirExtrato(String tipo) {
TipoExtrato.valueOf(tipo).processarExtrato();
}
}
Faz sentido?
S
O
L
I
D
S
O
L
I
D
ingle Responsibility Principle
S
O
L
I
D
ingle Responsibility Principle
pen/Closed Principle
S
O
L
I
D
ingle Responsibility Principle
pen/Closed Principle
iskov Substitution Principle
S
O
L
I
D
ingle Responsibility Principle
pen/Closed Principle
iskov Substitution Principle
nterface Segregation Principle
S
O
L
I
D
ingle Responsibility Principle
pen/Closed Principle
iskov Substitution Principle
nterface Segregation Principle
ependency Inversion Principle
Single Responsibility Principle
SRP
Uma classe deve ter apenas uma responsabilidade.
public class Automobile {
public void start() {}
public void stop() {}
public void changeTires([]Tire tires) {}
public void drive()
public void wash()
public int getOil()
}
SRP - técnica simples
Em uma folha de papel , escreva várias vezes:
"O(A) __________ __________ sozinho(a)."
"O(A) __________ __________ sozinho(a)."
"O(A) __________ __________ sozinho(a)."
"O(A) __________ __________ sozinho(a)."
"O(A) __________ __________ sozinho(a)."
"O(A) __________ __________ sozinho(a)."
SRP - técnica simples
Primeiro espaço, nome da classe. Segundo espaço, método.
"O automobile start sozinho."
"O automobile stop sozinho."
"O automobile changeTires sozinho."
"O automobile drive sozinho."
"O automobile wash sozinho."
"O automobile getOil sozinho."
SRP - técnica simples
Primeiro espaço, nome da classe. Segundo espaço, método.
"O automobile start sozinho."
"O automobile stop sozinho."
"O automobile changeTires sozinho."
"O automobile drive sozinho."
"O automobile wash sozinho."
"O automobile getOil sozinho."
SRP - técnica simples
Primeiro espaço, nome da classe. Segundo espaço, método.
"O automobile start sozinho."
"O automobile stop sozinho."
"O automobile changeTires sozinho."
"O automobile drive sozinho."
"O automobile wash sozinho."
"O automobile getOil sozinho."
SRP - técnica simples
Primeiro espaço, nome da classe. Segundo espaço, método.
"O automobile start sozinho."
"O automobile stop sozinho."
"O automobile changeTires sozinho."
"O automobile drive sozinho."
"O automobile wash sozinho."
"O automobile getOil sozinho."
SRP - técnica simples
Primeiro espaço, nome da classe. Segundo espaço, método.
"O automobile start sozinho."
"O automobile stop sozinho."
"O automobile changeTires sozinho."
"O automobile drive sozinho."
"O automobile wash sozinho."
"O automobile getOil sozinho."
SRP - técnica simples
Primeiro espaço, nome da classe. Segundo espaço, método.
"O automobile start sozinho."
"O automobile stop sozinho."
"O automobile changeTires sozinho."
"O automobile drive sozinho."
"O automobile wash sozinho."
"O automobile getOil sozinho."
SRP - técnica simples
Primeiro espaço, nome da classe. Segundo espaço, método.
"O automobile start sozinho."
"O automobile stop sozinho."
"O automobile changeTires sozinho."
"O automobile drive sozinho."
"O automobile wash sozinho."
"O automobile getOil sozinho."
public class Automobile {
public void start() {}
public void stop() {}
public int getOil()
}
public class Mechanic {
public void changeTires([]Tire tires) {}
}
public class Driver {
public void drive()
}
public classe CarWash {
public void wash()
}
Open / Closed Principle
Open / Closed Principle
Deve ser aberto para extensões e fechado para modificações.
- Mudar o comportamento sem alterar o código existente;
- Herança? Herança quebra o encapsulamento. Prefira a composição.
Liskov Substitution Principle
Liskov Substitution Principle
Objetos em um programa devem ser substituíveis com instâncias de seus subtipos, sem alterar a correção desse programa.
- Hashtable (Java) permite qualquer objeto como chave e valor;
- Properties (Java) estende Hashtable;
- Properties deveria receber apenas Strings como chave e valor.
Liskov Substitution Principle
Hashtable matricula = new Properties();
matricula.put("Marcio", "3542");
matricula.put("Marcelo", "4433");
matricula.put("Joaquim", 3224);
((Properties) matricula).list(System.out);
Liskov Substitution Principle
Hashtable matricula = new Properties();
matricula.put("Marcio", "3542");
matricula.put("Marcelo", "4433");
matricula.put("Joaquim", 3224);
((Properties) matricula).list(System.out);
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer
cannot be cast to java.lang.String at java.util.Properties.list(Unknown Source) at
...
Interface Segregation Principle
Interface Segregation Principle
Muitas interfaces específicas são melhores do que uma interface de uso geral".
- Implementar interface com comportamentos a mais?
- Enxugar os comportamentos das interfaces.
Interface Segregation Principle
type Worker interface {
work()
eat()
}
type Developer struct {}
func (*Developer) work() {}
func (*Developer) eat() {}
type Manager struct {}
func (*Manager) work() {}
func (*Manager) eat() {}
type Jaspion struct {} // Neoway Slack Bot...
func (*Jaspion) work() {}
func (*Jaspion) eat() {} // Ouch! :(
Dependency Inversion Principle
Dependency Inversion Principle
Dependa de abstrações. Não dependa de classes concretas.
type Developer struct {}
func (*Developer) work() {}
type Manager struct {
Developer *Developer
}
func (m *Manager) work() {
m.Developer.work()
}
Dependency Inversion Principle
Dependa de abstrações. Não dependa de classes concretas.
type Developer struct {}
func (*Developer) work() {}
type Manager struct {
Developer *Developer
}
func (m *Manager) work() {
m.Developer.work()
}
type Jaspion struct {}
func (*Jaspion) work() {}
Dependency Inversion Principle
Dependa de abstrações. Não dependa de classes concretas.
type Worker interface {
work()
}
type Manager struct {
Someone Worker
}
func (m *Manager) work() {
m.Someone.work()
}
type Developer struct {}
func (*Developer) work() {}
type Jaspion struct {}
func (*Jaspion) work() {}
Benefícios do SOLID
- Menos mudanças;
- Classes mais coesas;
- Menor acoplamento;
- Manutenção mais fácil.
You Aren't Gonna Need It
Keep It Simples, Stupid
(1970)
Obrigado!
Alguns princípios que todo desenvolver deve saber
By Ricardo Longa
Alguns princípios que todo desenvolver deve saber
- 1,490