Princípios de Projeto
Prof. Marco Tulio Valente
mtov@dcc.ufmg.br
1
Licença CC-BY; permite copiar, distribuir, adaptar etc; porém, créditos devem ser dados ao autor dos slides
Integridade Conceitual (1)
2
Integridade Conceitual (2)
3
Estratégias para promover integridade conceitual:
4
Integridade Conceitual = coerência e padronização de funcionalidades, projeto e implementação
5
Exemplo
Contra-Exemplo
Princípios SOLID
(ou seja, SOLID é um acrônimo de acrônimos)
6
Source: Clean Architecture: A Craftsman's Guide to Software Structure and Design, Robert Martin, 2017
(1) SRP: Single Responsibility Principle
7
CFO = contabilidade
COO = recursos humanos
CTO = tecnologia
(2) OCP: Open-Closed Principle
8
class List {
sort() {
// quicksort code
}
insert(...) { ... }
search(...) { ... }
}
class List {
SortStrategy strategy;
sort() {
strategy.sort()
}
insert(...) { ... }
search(...) { ... }
}
OCP: Open-Closed Principle
9
(3) LSP: Princípio de Substituição de Liskov
void f (T1 t) { ... t.g(); ... }
10
LSP: Definição mais formal
11
Exemplo de Código que não segue LSP
void f (Dicionario p) {
String s1 = p.traduz("book");
String s2 = p.traduz("principle");
....
}
class Dicionario {
String traduz (String); // Dicionario completo Inglês-Port
}
class DicionarioCompacto extends Dicionario {
String traduz (String); // Dicionario compacto, por exemplo, que não
// inclui a tradução de "principle"
}
12
Exemplo de Código que não segue LSP (cont.)
13
Exemplo de Código que segue LSP
void f (Dicionario p) {
String s1 = p.traduz("boy");
String s2 = p.traduz("principle");
....
}
class Dicionario {
String traduz (String); // Dicionario muito completo Inglês-Port
}
class DicionarioEstendido extends Dicionario {
String traduz (String);
}
14
Outro Exemplo sobre LSP
15
(4) Interface Segregation Principle (ISP)
16
Essa solução não segue ISP
Solução que segue ISP
17
(5) Dependency Inversion Principle (DIP)
18
Critérios para definir interfaces (Information Hiding)
19
Uma tradução "moderna" de Information Hiding�
20
Source: Engineering Software As a Service: An Agile Approach Using Cloud Computing, Armando Fox & David Patterson
Uma tradução "moderna" de Information Hiding�
21
Acoplamento & Coesão
22
Acoplamento e Coesão
23
Acoplamento
24
Acoplamento: é bom ou ruim?
25
Getters/setters: evitando acoplamento de dados
class Aluno {
private int matricula;
...
public int getMatricula() {
return matricula;
}
public setMatricula(int matricula) {
this.matricula = matricula;
}
}
26
Por que escrever getters e setters?
27
Por que escrever getters e setters?
28
Vantagens de baixo acoplamento
29
Episódio left-pad (sobre os riscos de acoplamento)
30
Episódio do left-pad: por que aconteceu?
31
Episódio do left-pad: resumo
32
Coesão
33
Coesão: Exemplo
void CalculaImprimeRaizesQuadradas(...) {
... // código que calcula raiz quadrada
... // código que imprime raizes
}
34
Qual destas duas classes é mais coesa?
35
class A {
private Obj _bla = new Obj();
public void FirstMethod() {
_bla.FirstCall();
}
public void SecondMethod() {
_bla.SecondCall();
}
public void ThirdMethod() {
_bla.ThirdCall();
}
}
class B {
private Obj _bla = new Objt();
private Obj _foo = new Obj();
private Obj _bar = new Obj();
public void FirstMethod() {
_bla.Call();
}
public void SecondMethod() {
_foo.Call();
}
public void ThirdMethod() {
_bar.Call();
}
}
Como medir acoplamento?
36
Como medir coesão?
37
Exercício: calcular LCOM(A) e LCOM(B)
38
class A {
private Obj _bla = new Obj();
public void FirstMethod() {
_bla.FirstCall();
}
public void SecondMethod() {
_bla.SecondCall();
}
public void ThirdMethod() {
_bla.ThirdCall();
}
}
class B {
private Obj _bla = new Objt();
private Obj _foo = new Obj();
private Obj _bar = new Obj();
public void FirstMethod() {
_bla.Call();
}
public void SecondMethod() {
_foo.Call();
}
public void ThirdMethod() {
_bar.Call();
}
}
Como medir a complexidade de uma função?
39
Exemplo de Complexidade Ciclomática (CC)
40
CFG (13 arestas, 11 nodos)
CC(sort) = 13 -11 + 2