Buscar

05a-Padrões GRASP

Prévia do material em texto

GRASP 
 General Responsibility Assignment Software Patterns 
 
 Os padrões GRASP fornecem uma abordagem 
sistemática para a atribuição de responsabilidades às 
classes do projeto 
 
GRASP 
 Qual é a conexão entre Responsabilidades, GRASP e 
diagramas UML? 
 A ocasião para considerar a atribuição de 
responsabilidades às classes é durante a elaboração dos 
diagramas de sequência 
 
Padrões GRASP 
Básicos 
Creator 
 Information 
Expert 
High Cohesion 
Low Coupling 
Controller 
Avançados 
Polymorphism 
Pure Fabrication 
 Indirection 
Protected 
Variants 
 
4 
O Criador (Creator) 
Problema: Quem deve ser responsável por criar uma nova instância de uma 
classe? 
Solução: Atribua à classe B a responsabilidade de criar uma instância de A se 
pelo menos um desses for verdadeiro (quanto mais melhor): 
• B contém ou agrega A 
• B registra a existência de A 
• B usa A 
• B tem os dados necessários para a inicialização de A que 
serão passados ao construtor de A 
Exemplo: Jogo de Banco Imobiliário 
Quem deve criar os objetos correspondentes às peças do tabuleiro? 
Exemplo: Jogo de Banco Imobiliário 
visão estática 
visão dinâmica 
Outro exemplo: um ponto de venda 
Cuidado com a Criação de 
Objetos Complexos 
Padrões GRASP 
Básicos 
Creator 
 Information 
Expert 
High Cohesion 
Low Coupling 
Controller 
Avançados 
Polymorphism 
Pure Fabrication 
 Indirection 
Protected 
Variants 
 
10 
O padrão Especialista (Information 
Expert) 
 Problema: 
 Precisa-se de um princípio geral para atribuir 
responsabilidades a objetos 
 Durante o projeto, em que são definidas as interações 
entre objetos, é preciso fazer escolhas sobre a atribuição 
de responsabilidades a classes. 
 Solução 
 Atribuir uma responsabilidade ao especialista de 
informação: classe que possui a informação necessária 
para cumpri-la; 
 Inicie declarando claramente a responsabilidade 
 
 
Exemplo: O Banco Imobiliário 
Quem deve localizar uma posição do tabuleiro dada a sua identidade? 
Exemplo: O ponto de venda 
Quem deve ser responsável por conhecer o total da venda? 
Exemplo: O ponto de venda 
Quem deve ser responsável por conhecer o total da venda? 
Exemplo: O ponto de venda 
Quem deve ser responsável por conhecer os subtotais? 
Exemplo: O ponto de venda 
Quem deve ser responsável por conhecer o preço de cada item 
de venda? 
Exemplo: O ponto de venda 
O padrão Especialista (Information 
Expert) 
 Benefícios: 
 O encapsulamento da informação é mantido uma vez que os objetos 
usam seus próprios dados para realizar as tarefas. 
 Baixo acoplamento entre as classes. 
 O comportamento do sistema é distribuído entre as classes que têm 
as informações, encorajando a definição de classes mais "leves", 
mais fáceis de entender e de manter. 
 Contraindicações : 
 Em algumas situações, a solução sugerida pelo especialista pode ser 
indesejada. (Quem deve persistir uma venda no banco?) 
 
Padrões GRASP 
Básicos 
Creator 
 Information 
Expert 
High Cohesion 
Low Coupling 
Controller 
Avançados 
Polymorphism 
Pure Fabrication 
 Indirection 
Protected 
Variants 
 
20 
Coesão Alta 
 Problema: 
 Como manter os objetos focados, compreensíveis, 
gerenciáveis e, em consequência, com Baixo 
Acoplamento? 
 Classes que fazem muitas tarefas não relacionadas são 
mais difíceis de entender, de manter e de reusar, além de 
mais vulneráveis às mudanças. 
 Solução: 
 Atribua responsabilidades de modo que a coesão da 
classe permaneça alta. Use esse critério para avaliar 
alternativas 
 
Coesão 
 Medida de quão relacionadas ou focadas estão as 
responsabilidades de um elemento. 
 Exemplo: 
 Cao é coesa se tem apenas operações relacionadas ao 
Cão (morder, correr, latir, comer) a apenas ao Cão. ‘~ao 
terá que imprimir, listar cães, etc... 
 Alta coesão promove design modular 
Coesão Alta 
Alta Coesão 
 Que classe é responsável por criar um pagamento 
(Payment) e associá-lo a uma venda (Sale) ? 
 
 
 
 
 
 
 
 Register assumiu responsabilidade por uma coisa que é 
parte de Sale (fazer um pagamento não é responsabilidade 
de registrar) 
Alta Coesão 
 Register delega a responsabilidade a Sale, aumentando a 
coesão de Register 
Coesão 
Uma classe com baixa coesão sofre dos 
seguintes problemas: 
 difícil de compreender 
 difícil de reutilizar 
 difícil de manter 
 frágil; frequentemente tem de ser alterada 
Coesão 
 Como um princípio básico, uma classe com alta 
coesão: 
 tem um número relativamente pequeno de métodos, 
 a funcionalidade desses métodos é altamente 
relacionada, e 
 não faz trabalho de mais. 
 
Padrões GRASP 
Básicos 
Creator 
 Information 
Expert 
High Cohesion 
Low Coupling 
Controller 
Avançados 
Polymorphism 
Pure Fabrication 
 Indirection 
Protected 
Variants 
 
29 
Baixo Acoplamento 
 Problema: 
 Como prover baixa dependência entre classes, reduzir o 
impacto de mudanças e obter alta reutilização? 
 
 Solução: 
 Atribua as responsabilidades de modo que o 
acoplamento entre classes permaneça baixo. Use este 
princípio para avaliar alternativas. 
 
Acoplamento 
 Medida de quanto um elemento está conectado a, ou 
depende de outros elementos. 
 Uma classe com acoplamento forte depende de muitas 
outras classes: tais classes podem ser indesejáveis 
 O acoplamento está associado à coesão: maior coesão, 
menor acoplamento e vice-versa. 
Exemplo: O Banco Imobiliário 
Pergunta: Por que o Tabuleiro e não um cachorro? 
Baixo Acoplamento 
 Ponto Chave: 
 O Especialista favorece o Baixo Acoplamento 
 Retornando à motivação do especialista: 
 conduz a soluções que favorecem o baixo acoplamento. 
O especialista nos pede que encontremos o objeto que 
tem a maior parte da informação necessária para assumir 
a responsabilidade (por exemplo, o tabuleiro) 
 Se pusermos a responsabilidade em algum outro lugar 
qualquer (por exemplo, o cachorro) o acoplamento 
global será maior porque mais informações terão de 
ser compartilhadas entre os objetos. 
 
Outro Exemplo: O ponto de venda 
Suponha que temos de criar um objeto pagamento e associá-lo à venda. 
Que classe deve ser responsável por isso? 
1ª alternativa 
2ª alternativa 
Acoplamento entre classes 
a) A ClasseA tem um atributo do tipo ClasseB 
Acoplamento entre classes 
b) A ClasseA tem um método que, de alguma forma, 
referencia uma instância de ClasseB. Tipicamente, esta 
referência se dá através de um parâmetro ou variável 
local do tipo ClasseB ou por um objeto do tipo ClasseB 
retornado pela chamada de algum método 
Acoplamento entre classes 
c) A ClasseA é uma subclasse de ClasseB 
Acoplamento entre classes 
d) A ClasseB é uma interface e a ClasseA implementa esta 
interface 
Acoplamento entre classes 
 Discussão: 
 Classes que, por natureza, são genéricas e que têm alta 
probabilidade de reutilização deveriam ter acoplamento 
baixo 
 O caso extremo do baixo acoplamento é o não 
acoplamento: contraria o princípio da orientação a 
objetos: 
 objetos conectados, trocando mensagens entre si. 
 O acoplamento alto não é o problema em si. O problema 
é o acoplamento a classes que, de alguma forma são 
instáveis: 
 sua interface, sua implementação ou sua mera presença. 
 
Padrões GRASP 
Básicos 
Creator 
 Information 
Expert 
High Cohesion 
Low Coupling 
Controller 
Avançados 
Polymorphism 
Pure Fabrication 
 Indirection 
Protected 
Variants 
 
41 
O Controlador 
 Problema: 
 Quem deve ser o responsável por lidar com um evento de 
uma interface de entrada? 
 Solução: 
 Atribuir a responsabilidade de receber ou lidar com um 
evento do sistema para uma classe que representa todo o 
sistema (controlador de fachada – front controller), um 
subsistema e um cenário de casos de uso (controlador de 
caso de uso ou sessão) 
O ControladorQue objeto, fora da camada de apresentação, deve receber e 
coordenar a solicitação da execução de uma operação? 
O princípio da separação Modelo-
Vista 
O princípio da separação Modelo-Vista pode ser enunciado em duas 
partes: 
• Não conecte diretamente objetos pertencentes à 
interface com o usuário (a vista) com objetos não 
pertencentes à interface com o usuário (IU). 
• Não coloque lógica da aplicação (tal como o cálculo 
de impostos) nos métodos dos objetos da IU 
 
O princípio da separação Modelo-
Vista 
A motivação para a separação Modelo-Vista inclui: 
• Suportar a criação de classes de negócio coesas, com foco 
nos processos do domínio ao invés de na interface com o 
usuário. 
• Permitir o desenvolvimento separado das camadas de 
apresentação e negócio. 
• Minimizar o impacto na camada de negócio das alterações 
nos requisitos da interface com o usuário. 
O princípio da separação Modelo-
Vista 
• Permitir que novas vistas sejam facilmente conectadas 
aos objetos de negócio existentes, sem afetar a camada 
de negócios. 
• Permitir a existência de múltiplas vistas simultâneas para 
uma mesma camada de negócios (por exemplo, a 
visualização de dados de vendas na forma tabular ou 
através de um gráfico de pizzas) 
A motivação para a separação Modelo-Vista inclui: 
O objeto Controlador 
O objeto Controlador responde a uma questão básica no 
projeto de sistemas OO: Como conectar a camada de 
apresentação à camada da lógica do negócio? 
O objeto Controlador 
O controlador é o primeiro objeto fora da camada de interface com o 
usuário a receber ou tratar uma mensagem para o sistema. 
Existem duas alternativas possíveis para o objeto controlador: 
• Um objeto Controlador para todo o sistema 
• Um objeto Controlador por Caso de Uso (ou por cenário 
de Caso de Uso) 
Controlador 
 Um sistema contendo operações “de sistema” 
associados com eventos do sistema 
Controlador 
 Os benefícios do padrão controlador são: 
 Diminui a sensibilidade da camada de 
apresentação em relação à lógica de domínio 
 Oportunidade para controlar o estado do caso de 
uso 
 
Exemplo: Ponto de Venda 
Padrões GRASP 
Básicos 
Creator 
 Information 
Expert 
High Cohesion 
Low Coupling 
Controller 
Avançados 
Polymorphism 
Pure Fabrication 
 Indirection 
Protected 
Variants 
 
53 
Polimorfismo 
 Problema: 
 Como tratar alternativas baseadas no tipo? Como criar 
componentes de software "plugáveis"? 
 Deseja-se evitar variação condicional (if-then-else): 
pouco extensível 
 Deseja-se substituir um componente por outro sem 
afetar o cliente 
 Solução: 
 Quando alternativas ou comportamentos relacionados 
variam com o tipo (classe), atribua as responsabilidades 
aos tipos usando operações polimórficas. 
 
Exemplo 
O Banco Imobiliário 
Como projetar para acomodar as diferentes ações baseadas 
no tipo da posição do tabuleiro? 
Um mau projeto: 
O Banco Imobiliário 
O comportamento estático: 
O Banco Imobiliário 
O comportamento dinâmico: 
O Banco Imobiliário 
O comportamento dinâmico: 
O Banco Imobiliário 
O comportamento dinâmico: 
O Banco Imobiliário 
O comportamento dinâmico: 
O Banco Imobiliário 
O comportamento dinâmico: 
Padrões GRASP 
Básicos 
Creator 
 Information 
Expert 
High Cohesion 
Low Coupling 
Controller 
Avançados 
Polymorphism 
Pure Fabrication 
 Indirection 
Protected 
Variants 
 
64 
Pure Fabrication 
 Problema: 
 Que objeto deve ter a responsabilidade quando você não quer violar 
"Alta Coesão" e "Baixo Acoplamento", mas as soluções oferecidas 
pelo "Especialista" não são apropriadas? 
 Atribuir responsabilidade apenas para as classes do domínio 
conceitual pode levar a situações de maior acoplamento e menor 
coesão. 
 Solução: 
 Atribua um conjunto coeso de responsabilidades a uma classe 
artificial que não representa um conceito no domínio da aplicação, 
uma classe fictícia que possibilite alta coesão, baixo acoplamento e o 
reuso. 
 
Ponto de Venda: Salvar uma Venda 
no Banco de Dados 
O especialista nos diz para atribuir a responsabilidade à 
classe Venda, uma vez que ela conhece os dados da 
venda. Considere no entanto as seguintes implicações: 
 Salvar um objeto no Banco de Dados implica em uma 
série de operações não relacionadas ao conceito de 
venda 
 A classe venda tem de ser associada à interface do 
banco de dados relacional (JDBC, por exemplo) 
 Várias outras classes no projeto terão de fazer a mesma 
coisa. 
Pure Fabrication 
O Banco de Dados 
Padrões GRASP 
Básicos 
Creator 
 Information 
Expert 
High Cohesion 
Low Coupling 
Controller 
Avançados 
Polymorphism 
Pure Fabrication 
 Indirection 
Protected 
Variants 
 
70 
Indireção 
 Problema: 
 Onde colocar uma responsabilidade de modo a evitar o 
acoplamento direto entre duas ou mais classes? 
 Como desacoplar objetos de modo a possibilitar o baixo 
acoplamento e manter alta a possibilidade de reuso? 
 Solução: 
 Atribua a responsabilidade a um objeto intermediário que faça a 
mediação entre componentes ou serviços de modo que eles não 
sejam diretamente acoplados 
 O objeto intermediário cria uma camada de indireção entre os dois 
componentes que não mais dependem um do outro: ambos 
dependem da indireção 
Indireção 
Exemplo: Indireção através de um adaptador 
Indireção 
"A maior parte dos problemas em Ciência da Computação 
pode ser resolvida por um nível adicional de indireção" 
 
 Velho provérbio com especial relevância para 
 sistemas orientados a objetos 
 
 
"A maior parte dos problemas de desempenho pode ser resolvida removendo-se algumas 
camadas de indireção" 
INVERSÃO DE 
CONTROLE 
Inversão de Controle – IoC 
 Princípio de Hollywood: 
 “Não nos ligue, nós ligaremos”. 
 Dependência de componentes. 
 também conhecida como colaboradores de objetos. 
 O objeto que exige dependência é conhecido como 
objeto dependente. 
 Frameworks é responsável pela execução da operação. 
 Ocorre em tempo de execução. 
76 
Inversão de Controle: 
Motivação – Cenário 1 
 Classe A precisa de uma referência para a Classe B. 
 Classe B é uma classe concreta que tem um construtor 
padrão. 
 Classe A possui uma instância de B. 
 Nenhuma outra classe pode acessar uma instância da 
Classe B [Mal06]. 
 
77 
 
 
public class A{ 
private B b; 
public A(){ 
 b=new B(); 
} 
} 
Inversão de Controle: 
Motivação – Cenário 2 
 Objeto a possui referência para os objetos c e b. 
 
78 
 
 
public class A{ 
private B b; 
 public A(){ 
 C c = new C(); 
 b = new B(c); 
 } 
} 
Inversão de Controle: 
Motivação – Cenário 3 
 A precisa de uma referência para B, e não precisa saber 
como B é instanciado. 
 B pode ser uma interface, uma classe abstrata ou 
concreta. 
 Antes de instanciar a classe A, precisa de uma 
referência para a classe B. 
 
79 
 
 
public class A{ 
private B b; 
 public A(){ } 
 public setB(B b){ 
 this.b=b; 
 } 
} 
Tipos de Inversão de Controle 
 
 Inversão de Controle (IoC) possui dois tipos [Har05]: 
 
 Injeção de Dependência (Dependency Injection) 
 
 Procura por Dependência (Dependency Lookup) 
 
 Injeção de Dependência sempre diz respeito a IoC, 
mas IoC nem sempre referencia Injeção de 
Dependência 
80 
81 
Tipos de Inversão de Controle 
Inversão de 
Controle
Procura por 
Dependência
Injeção de 
Dependência
Contextualized 
Dependency 
Lookup 
Dependency 
Pull
Interface Setter Construtor
 
Tipos de Inversão de Controle 
 Procura por Dependência: 
 um componente deve obter uma referência para uma dependência; 
 dois subtipos: 
 Dependency Pull 
 Contextualized Dependency Lookup (CDL) 
 
 Injeção de Dependência: 
 as dependências são literalmente injetadas (incluídas) 
 três subtipos: 
 Interface – Tipo 1 
 Setter – Tipo 2 
 Constructor – Tipo 3 
82 
Contêineresde Inversão de 
Controle 
 Spring 
 
 Avalon 
 
 PicoContainer 
 
 HiveMind 
 
 
 Excalibur: Fortress 
 
 Resin 
 
 Copland (Ruby) 
 
 Mentawai 
 
83 
Procura por Dependência — 
Dependency Pull 
 As dependências são obtidas através de um registro 
assim que necessário; 
 Mecanismo para encontrar componentes que 
gerenciam o frameworks. 
84 
 
Procura por Dependência com Spring 
 
public static void main(String[] args) throws Exception { 
 
// get the bean factory 
BeanFactory factory = getBeanFactory(); 
 
MessageRenderer mr = (MessageRenderer) factory.getBean("renderer"); 
mr.render(); 
} 
Procura por Dependência — 
Contextualized Dependency Lookup 
(CDL) 
 
 Semelhante ao Dependency Pull; 
 Procura é executada pelo contêiner que está 
gerenciando o recurso e não a partir de um registro 
central; 
 CDL funciona através da implementação de uma 
interface. 
85 
 
Interface do Componente para CDL com Spring 
 
public interface ManagedComponent { 
 
public void performLookup(Container container); 
 
} 
 
Procura por Dependência — 
Contextualized Dependency Lookup 
(CDL) 
 
 Executa o método performLookup() implementado 
pelo componente; 
 O componente pode procurar sua dependência 
utilizando a interface Container. 
86 
 
Obtendo dependência com o CDL 
 
public class ContextualizedDependencyLookup implements 
ManagedComponent { 
private Dependency dep; 
 
public void performLookup(Container container) { 
 this.dep = (Dependency)container.getDependency 
 ("myDependency"); 
 } 
} 
 
Dependency Injection 
 Problema 
 Controle convencional: o próprio objeto cria ou localiza 
suas dependências: acoplamento 
87 
Injeção de Dependência — 
por meio de Construtor 
 Dependência do componente é disponibilizada através 
de seu(s) construtor(es); 
 O argumento recebido será sua dependência. 
88 
 
Injeção de Dependência pelo Construtor com Spring 
 
public class ConstructorInjection { 
 
private Dependency dep; 
 
public ConstructorInjection(Dependency dep) { 
 this.dep = dep; 
 } 
} 
 
Injeção de Dependência — 
por meio de método Setter 
 O contêiner IoC injeta um componente de 
dependência através de seu método set (JavaBean); 
 O componente setter permite um conjunto de 
dependências que o contêiner de inversão de controle 
pode gerenciar. 
89 
 
Injeção de Dependência através do método Setter com Spring 
 
 
public class SetterInjection { 
 
private Dependency dep; 
 
public void setMyDependency(Dependency dep) { 
 this.dep = dep; 
 } 
} 
 
Injeção de Dependência — 
por meio de Interface [Fow06] 
 Componente de dependência através de uma interface; 
 A interface InjectFinder será definida por 
qualquer um que fornecer a interface MovieFinder 
(no exemplo abaixo). 
90 
 
Injeção de Dependência através de Interface. Exemplo no arcabouço Avalon 
 
public interface InjectFinder { 
 
public void injectFinder(MovieFinder finder); 
} 
 
public class MovieLister implements InjectFinder { 
 
public void injectFinder(MovieFinder finder){ 
 this.finder = finder; 
} 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Injeção de Dependência — 
por meio de Interface 
 Exemplo: 
 Classe de Teste no Avalon: configura os componentes e 
os injetores. 
 
91 
 
public class Tester { 
 
private Container container; 
 
private void configureContainer(){ 
 container = new Container(); 
 registerComponents(); 
 registerInjectors(); 
 container.start(); 
} 
} 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Injeção de Dependência — 
por meio de Interface 
 É preciso registrar os injetores que irão injetar os 
componentes dependentes; 
 Cada interface de injeção precisa de algum código para 
injetar o objeto dependente; 
 No código abaixo, registram-se os objetos injetores no 
contêiner: 
92 
 
private void registerInjectors(){ 
 
container.registerInjector(InjectFinder.class, 
 container.lookup(“MovieFinder”)); 
} 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Injeção versus Procura 
 O tipo de IoC é definido pelo contêiner adotado. 
 Com Dependency Pull, é necessário: 
 registrar dependências; 
 obter referências das dependências; 
 interagir com as dependências obtidas. 
 Utilizando CDL, é preciso: 
 que as classes implementem uma interface específica; 
 e procure por todas dependências manualmente. 
 Com Injeção de Dependência, as classes precisam: 
 permitir que as dependências sejam injetadas por meio 
de construtores, métodos setters ou interfaces. 
93 
Inversão de Controle e Padrão 
Reactor 
 Reactor: Padrão de Arquitetura [POSA 2]; 
 Conhecido também como 
 Dispatcher, Notifier 
 Contexto: 
 Aplicação orientada a eventos que processa as 
informações de forma síncrona e serial. 
 Problema: aplicações devem: 
 atender muitas requisições simultaneamente, 
 demultiplexar e despachar as indicações de eventos às 
respectivas implementações de serviço. 
94 
Inversão de Controle e Padrão 
Reactor 
 Define uma interface que permite que aplicações: 
 registrem ou removam tratadores de eventos; 
 sejam executadas no laço de eventos da aplicação. 
 Reactor utiliza um demultiplexador síncrono de evento 
para aguardar pela indicação de eventos que se 
originam de uma ou mais fontes. 
 Quando ocorre um evento: 
 o demultiplexador síncrono de evento notifica o Reactor; 
 o Reactor aciona o tratador associado, para realização do 
serviço solicitado. 
 O Reactor inverte o fluxo de controle, pois é 
responsabilidade dele (e não da aplicação) em disparar 
os tratadores concretos para cada tipo de evento. 
95 
Desvantagens na Inversão de 
Controle 
 Dificuldade na integração de arcabouços: 
 quando dois ou mais frameworks chamam 
simultaneamente o código da aplicação, cada qual 
pressupondo seu próprio fluxo de controle; 
 
 Dificuldade na depuração do código e 
compreensão do fluxo: 
 o controle é alternado entre o código da aplicação e o 
código do frameworks. 
 
96 
Injeção de Dependências 
(Inversão de Controle) 
 Um dos benefícios de usar interface 
 Em vez de 
 
 
 Use 
 
Injeção de Dependências 
(Inversão de Controle) 
 Se A depende de InterB, fica fácil testar ou media A usando uma 
implementação/simulação de B para testes 
 
 
 
 
 
 Interfaces devem ser pequenas 
 Um objeto pode implementar várias interfaces 
 Facilita a evolução (interfaces grandes publicam um contrato grande 
que não pode ser revogado. 
 Planeje interfaces em todos os objetos 
 Principalmente nos que oferecem serviços, singleton, etc.. 
Exemplo: controle convencional 
 Linha 9: dependência fortemente acoplada 
 Difícil de testar objeto sem testar dependência 
99 
A dependência 
100 
Diminuindo o acoplamento 
 Melhor forma de eliminar o acoplamento é usar interfaces 
 Implementação é dependente da interface 
 Cliente depende da interface, não mais da implementação 
101 
Solução 
 Em vez do programador buscar ou criar sua própria 
certificação, ela é atribuída a ele 
 Para isto, deve haver método para criar a associação 
102 
Inversão de Controle 
103 
Padrões GRASP 
Básicos 
Creator 
 Information 
Expert 
High Cohesion 
Low Coupling 
Controller 
Avançados 
Polymorphism 
Pure Fabrication 
 Indirection 
Protected 
Variants 
 
104 
Protected Variants 
 Problema: 
 Como projetar objetos, subsistemas e sistemas para que as variações 
ou instabilidades nesses elementos não tenha um impacto 
indesejável nos outros elementos? 
 Solução: 
 Identificar pontos de variação ou instabilidades potenciais 
 Atribuir responsabilidades para criar uma interface estável em volta 
desses pontos. 
 Encapsulamento, interfaces, polimorfismo, indireção e padrões: 
máquinas virtuais e brokers são motivados por este princípio 
 Evite enviar mensagens a objetos muito distantes 
 
Aspectos 
Adicionais 
Aspectos: separação de 
interesses 
 A separação de interesses é objetivo essencial do processo 
de decomposição da solução de um problema Decomposição deve continuar até que cada unidade da solução 
possa ser compreendida e construída 
 Cada unidade deve lidar com apenas um interesse 
 Separação de interesses eficiente promove o código de 
melhor qualidade 
 Maior modularidade 
 Facilita atribuição de responsabilidades entre módulos 
 Promove o reuso 
 Facilita a evolução do software 
 Viabiliza a análise do problema dentro de domínios específicos 
107 
Tipos de interesse 
 Usando linguagem OO, pode-se representar de forma 
eficiente e modular as classes e procedimentos 
 Outros interesses são implementados como partes de 
classes e partes ou composição de procedimentos 
108 
Scattering e tangling 
109 
Inclusão de nova 
funcionalidade 
 Também sujeita a scattering e tangling 
 Funcionalidade espalhada por várias classes (funcionalidade 
consiste de métodos contidos em várias classes) 
 Funcionalidades misturadas com outros recursos (não é 
representado por uma entidade separada) 
110 
Como reduzir tangling e scattering 
 Criar subclasse que implemente 
recursos, sobreponha métodos, etc. 
 Problema: classes cliente têm que ser 
alteradas para que saibam como criar a 
nova subclasse: 
 VeiculoCarga v = 
 // new VeiculoCarga(); 
 new VeiculoCarga2(); 
 Design patterns como factory method 
resolveriam o problema 
 VeiculoCarga v = 
 VeiculoCarga.create(); 
mas sua interface precisaria ser 
planejada antes. 
111

Continue navegando