padrões - início | faculdade de computaçãoflavio/poo2/files/2011-02/patterns.pdf10/6/2011 1...
TRANSCRIPT
10/6/2011
1
Padrões Um padrão de é uma maneira de documentar uma solução conhecida para um problema
usualmente encontrado
O objetivo do padrão é permitir que boas soluções sejam reutilizadas em diferentes projetos
Um padrão de projeto possui 3 partes distintas: Contexto
Problema recorrente neste contexto
Solução para o problema
Características dos Padrões de Projeto São observados através da experiência
São descritos de uma forma estruturada
Previnem contra a “reinvenção da roda”
Existem em diferentes níveis de abstração
Estão em desenvolvimento contínuo
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
São artefatos reutilizáveis
Transmitem melhores práticas
Permitem o uso de um vocabulário comum
Podem ser utilizadas em conjunto para resolver um problema mais amplo
56
Classificação de PadrõesPadrões Os padrões de projeto podem ser classificados de acordo
com a fase de desenvolvimento em que são mais adequados: Padrões de Análise (Analysis patterns)
Seu foco é na fase de análise ou modelamento de negócio
Muita das vezes os padrões estão ligados ao domínio do problema o que pode
Padrões de Arquitetura (Architectural patterns) Seu foco é na arquitetura do software
Padrões de Projeto (Design patterns)
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
Padrões de Projeto (Design patterns) Foco no projeto de componentes do software
Muitas das vezes os padrões podem estar muito ligados tanto ao domínio da solução, quanto do problema
57
10/6/2011
2
Classificação de PadrõesPadrões Padrões de Análise (Analysis patterns)
Martin Fowler , 1996
Padrões de Arquitetura (Architectural patterns) Apresentado inicialmente por Frank Buschmann et al., 1996
Computação Distribuída - Frank Buschmann et al., 2007
Padrões de Projeto (Design patterns) GOF (Gang of Four) E. Gamma, R. Helm, R. Johnson, J. Vlissides – 1995
Aplicações Concorrentes e em Rede - Frank Buschmann et al. – 2000
Enterprise Integration Patterns – Gregor Hohpe, 2003
Real-time Design Patterns – Bruce Douglass, 2003
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
.Net Design Patterns - Christian Thilmany, 2003
J2EE Design Patterns - Deepak Alur, 2003
Web Services Patterns – Paul Monday, 2003
Ajax Design Patterns - Michael Mahemoff, 2006
SOA Design Patterns – Thomas Erl, 2009
58
Padrões de Análise(Analysis Patterns) Proposto por Martin Fowler, em livro publicado em 1996
Notação do Livro não é baseada em UML
Baseada em áreas (domínios) específicas como: manufatura; financeira e saúde
Mesmo assim padrões podem apresentados podem ser úteis em outros Mesmo assim, padrões podem apresentados podem ser úteis em outros domínios
Alguns princípios apresentados Um modelo não está certo ou errado, eles podem ser mais ou menos úteis
Modelos conceituais estão ligados a tipos (interfaces) e não implementações (classes)
Padrões são o ponto de partida, não o destino
Sempre que possível, quando existir um tipo e um supertipo, considere colocar os recursos no supertipo, desde que isto faça sentido
Q d úl i ib l i d
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
Quando múltipos atributos possuam um comportamento relacionado e presente em muitos tipos, combine estes atributos em um novo tipo fundamental
59
10/6/2011
3
Padrões de Análise(Analysis Patterns) Exemplos de alguns padrões de projeto
Quantity (3.1)
Conversion Ratio (3.2)
C d U it (3 3) Compound Units (3.3)
Measurement (3.4)
Observation (3.5)
Range (4.3)
Name (5.1)
Account (6.1)
Transaction (6.2)
S A (6 3)
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
Summary Account (6.3)
Plan (8.4)
Contract (9.1)
Product (10.3)
Associative Type (15.1)
60
Padrões de ProjetoGoF Trabalho proposto inicialmente por Erich Gamma, Richard Helm, Ralph
Jonhson, John Vlissides (Gang of Four) em 1995
Famílias de PadrõesD C i ã De Criação Responsáveis pela criação de objetos
Permitem que o sistema fique independente da forma como os objetos são criados
Estruturais Relacionados com a forma com que classes e objetos são compostos a fim de
formar estruturas maiores
Comportamentais Relacionados com a atribuição de responsabilidades entre objetos
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
Descrevem a comunicação entre objetos
61
10/6/2011
4
Padrões de Criação Factory
Fornece uma interface para criar um objeto, porém a decisão de qual classe será instanciada é decidida pelas subclasses
Abstract Factoryy Fornecem uma interface para criação de objetos sem especificar sua classe concreta
Singleton Garante que apenas uma classe possua uma única instância e oferece um acesso
global à mesma
Builder Permite separar a construção de um objeto complexo de sua representação a fim de
que diferentes objetos sejam criados através do mesmo processo
Prototype
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
Prototype Permite que um objeto seja criado a partir de uma instância existente copiando suas
propriedades
62
Factory Permite que um objeto seja criado sem que seja necessário informar a
classe exata que será criada
Separa a complexidade de criação do objeto
Uma interface define um método padrão para criação
Subclasses implentam este método e devolvem o objeto desejado
A fábrica implementa o método criando o objeto conforme necessário
class GOF - Factory
«interface»
ImageReader
+ getDecodedImage() : DecodedImage
ImageReaderFactory
+ getImageReader(InputStream) : ImageReader
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
63
GifReader
+ getDecodedImage() : DecodedImage
JpegReader
+ getDecodedImage() : DecodedImage
10/6/2011
5
FactoryExemplopublic interface ImageReader {
public DecodedImage getDecodedImage();
}
public class GifReader implements ImageReader {
public DecodedImage getDecodedImage() {
// ...
return decodedImage;
}
}
public class JpegReader implements ImageReader {
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
64
public class JpegReader implements ImageReader {
public DecodedImage getDecodedImage() {
// ...
return decodedImage;
}
}
FactoryExemplopublic class ImageReaderFactory {
public static ImageReader getImageReader(InputStream is) {
int imageType = determineImageType(is);
switch(imageType) {( g yp ) {
case ImageReaderFactory.GIF:
return new GifReader(is);
case ImageReaderFactory.JPEG:
return new JpegReader(is);
// etc.
}
}
}
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
65
}
10/6/2011
6
Abstract Factory Permite que objetos sejam criados de forma transparente caso exista um
grupo de diferente fábricas class Design Pattern - Abstract Factory
A li ti R
«interface»
GUIFactory
+ createButton() : Button
«interface»
Button
+ paint() : void
Application
+ Application(GUIFactory)
ApplicationRunner
+ main(String[]) : void+ createOsSpecificFactory() : GUIFactory
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
66
WinFactory
+ createButton() : Button
OSXFactory
+ createButton() : Button
WinButton
+ paint() : void
OSXButton
+ paint() : void
Abstract Factoryinterface GUIFactory {
public Button createButton();
}
class WinFactory implements GUIFactory {y p y {
public Button createButton() {
return new WinButton();
}
}
class OSXFactory implements GUIFactory {
public Button createButton() {
return new OSXButton();
}
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
}
}
67
10/6/2011
7
Abstract Factoryinterface Button {
public void paint();
}
class WinButton implements Button {
bli id i t() {public void paint() {
System.out.println("I'm a WinButton");
}
}
class OSXButton implements Button {
public void paint() {
System.out.println("I'm an OSXButton");
}
}
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
68
Abstract Factoryclass Application {
public Application(GUIFactory factory) {
Button button = factory.createButton();
button.paint();
}}
}
public class ApplicationRunner {
public static void main(String[] args) {
new Application(createOsSpecificFactory());
}
public static GUIFactory createOsSpecificFactory() {
i t dF C fi Fil ("OS TYPE")
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
int sys = readFromConfigFile("OS_TYPE");
if (sys == 0) {
return new WinFactory();
} else {
return new OSXFactory();
}
}
}69
10/6/2011
8
Singleton Objetivo
Garante que existirá uma única instância de um objeto de uma classe e permite um acesso global ao mesmo
Motivação Motivação Em muitas situações é necessário um único objeto. Exemplos:
O objeto que representa um sistema de arquivos do Sistema Operacional
Um objeto que representa um arquivo de configuração de uma aplicação
Um objeto que representa uma conexão com um banco de dados
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
70
SingletonExemplopublic class Singleton {
//instância de um objeto da classe Singleton
//inicializada com a chamada do construtor
private static Singleton instance = new Singleton();private static Singleton instance = new Singleton();
//Construtor privado impede criação de objetos desta classe
private Singleton() {
//lógica para criação do objeto
}
// ét d táti t ú i i tâ i d l
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
//método estático que retorna a única instância da classe
public static Singleton getInstance() {
return instance;
}
}
71
10/6/2011
9
SingletonExemplo - Outra abordagem
public class Singleton {
// Private constructor prevents instantiation from other classes
private Singleton() {
}}
/**
* SingletonHolder is loaded on the first execution of Singleton.getInstance()
* or the first access to SingletonHolder.INSTANCE, not before.
*/
private static class SingletonHolder {
bli t ti fi l Si l t i t Si l t ()
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
public static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}72
Padrões Estruturais Adapter
Bridge
Composite
Decorator Decorator
Facade
Proxy
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
73
10/6/2011
10
Adapter Objetivo
Converter uma interface de uma classe para uma interface compatível com a esperada
Permite que classes possam cooperar o que não seria possível pela Permite que classes possam cooperar o que não seria possível pela incompatibilidade entre as interfaces
Traduz as chamadas de sua interface para chamadas da interface da classe adaptada
Também conhecida como “Wrapper”
Uso Este padrão de projeto é útil em situações onde uma classe já existente
possui serviços que serão utilizados, porém não na Interface necessária
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
p ç q , p
Por exemplo, uma classe que espera valores boleanos
74
AdapterExemplo Um novo método para adicionar inteiros será utilizado em uma implementação
O código disponível porém apenas permite a adição de números binários (BinaryCalulator)
A classe CalculatorAdapter permitirá o uso da implementação disponível A classe CalculatorAdapter permitirá o uso da implementação disponível (BinaryCalculator), porém adatapada o
class GOF-Adapter
«interface»
ICalculator
+ add(int, int) : int
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
75
BinaryCalculator
+ add(String, String) : string
CalculatorAdapter
- bcalc: BinaryCalculator
+ CalculatorAdapter(bcalc)+ add(int, int) : int
10/6/2011
11
AdapterExemplopublic interface ICalculator{
public int add(int ia , int ib);
}
public class BinaryCalculator {p y {
public static string add(String sa,String sb){ //…
}
}
public class CalculatorAdapter implements ICalculator {
private BinaryCalculator bcalc;
public CalculatorAdapter(bcalc c){
bcalc = c;
}
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
}
public int add(int ia, int ib){
String result;
result = bcalc.add(Integer.toBinaryString(ia), Integer.toBinaryString(ib),
//converts binary string to a decimal representation return is value
return Integer.valueOf(result,10).intValue();
}
} 76
AdapterOutro Exemplo Dois exemplos de classes adptadoras. Uma baseada em uso
(DListToStackAdapter) e outra em herança múltipla (DListStackAdapter)
class GOF-Adapterp
«interface»
Stack
+ push(T) : void+ pop() : T+ top() : T
T
DList
+ insert(DNode, T) : void+ remove(DNode, T) : void+ insertHead(T) : void+ insertTail(T) : void+ removeHead() : T+ removeTail() : T+ getHead() : T+ getTail() : T
T
DListStackAdapter
T
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
77
p
+ push(T) : void+ pop() : T+ top() : T
DListToStackAdapter
- m_List: DList<T>
+ DListToStackAdapter(DList<T>)+ push(T) : void+ pop() : T+ top() : T
10/6/2011
12
Decorator Objetivo
Permite adicionar responsabilidades a um objeto de forma dinâmica
Desta forma não é necessário criar subclasses a fim de estender a funcionalidade dos objetosfuncionalidade dos objetos
Motivação Em alguns casos deseja-se adicionar responsabilidades a um objeto e não a
uma classe inteira
Exemplo Considere a modelagem de um cardápio de cafés onde é possível acrescentar
diversos acompanhamentos a um café
Como calcular o custo de cada item disponível no cardápio? Criar uma classe para
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
cada opção não é melhor alternativa
Neste caso o Decorator pode ser uma opção para a modelagem
78
DecoratorExemplo Baseado Capítulo 3, do livro “Head First Design Pattern”
Neste exemplos as bedidas (DarkRoast, Decaf, Espresso, HouseBlend) pode ser decoradas com diferentes acompanhamentos (Milk, Chocolate, Sugar, Cream)
l GOF D t class GOF-Decorator
Beverage
# description: String = "Unknown Beverage"
+ getDescription() : String+ cost() : double
CondimentDecorator
+ getDescription() : String
DarkRoast
+ DarkRoast()+ cost() : double
Decaf
+ Decaf()+ cost() : double
Espresso
+ Espresso()
HouseBlend
+ HouseBlend()+ cost() : double
Milk
- beverage: Beverage
+ Milk(Beverage)+ getDescription() : String+ cost() : double
Chocolate
Cream
- beverage: Beverage
+ Cream(Beverage)+ getDescription() : String+ cost() : double
StarbuzzCoffee
+ main(String[]) : void
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
79
+ Espresso()+ cost() : double
+ cost() : double
- beverage: Beverage
+ Chocolate(Beverage)+ getDescription() : String+ cost() : double
Sugar
- beverage: Beverage
+ Sugar(Beverage)+ getDescription() : String+ cost() : double
10/6/2011
13
DecoratorExemplo - Códigopublic abstract class Beverage {
protected String description = "Unknown Beverage“;
public String getDescription() {
return description;p ;
}
public abstract double cost();
}
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
80
DecoratorExemplo - Códigopublic class DarkRoast extends Beverage {
public DarkRoast() { description = "Dark Roast Coffee“; }
public double cost() { return .99; }
}}
public class Decaf extends Beverage {
public Decaf() {description = "Decaf Coffee"; }
public double cost() { return 1.05; }
}
public class Espresso extends Beverage {
public Espresso() { description = "Espresso“; }
public double cost() { return 1 99; }
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
public double cost() { return 1.99; }
}
public class HouseBlend extends Beverage {
public HouseBlend() { description = "House Blend Coffee"; }
public double cost() { return .89; }
}
81
10/6/2011
14
DecoratorExemplo - Códigopublic class Milk extends CondimentDecorator {
private Beverage beverage;
public Milk(Beverage beverage) { this.beverage = beverage; }
public String getDescription() {return beverage.getDescription() + ", Milk"; }p g g p () { g g p () , ; }
public double cost() { return .10 + beverage.cost(); }
}
public class Chocolate extends CondimentDecorator {
private Beverage beverage;
public Chocolate(Beverage beverage) { this.beverage = beverage; }
public String getDescription() { return beverage.getDescription() + ", Chocolate“; }
public double cost() { return .20 + beverage.cost(); }
}
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
}
public class Sugar extends CondimentDecorator {
private Beverage beverage;
public Sugar(Beverage beverage) { this.beverage = beverage; }
public String getDescription() { return beverage.getDescription() + ", Sugar"; }
public double cost() { return .15 + beverage.cost(); }
}82
DecoratorExemplo - Códigopublic class Cream extends CondimentDecorator {
private Beverage beverage;
public Cream(Beverage beverage) {p ( g g ) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", Cream";
}
public double cost() {
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
public double cost() {
return .10 + beverage.cost();
}
}
83
10/6/2011
15
DecoratorExemplo - Códigopublic class StarbuzzCoffee {
public static void main(String args[]) {
Beverage beverage = new Espresso();
System.out.println(beverage.getDescription() + " $" + beverage.cost());y p ( g g p () $ g ());
Beverage beverage2 = new DarkRoast();
beverage2 = new Chocolate(beverage2);
beverage2 = new Milk(beverage2);
beverage2 = new Cream(beverage2);
System.out.println(beverage2.getDescription()+ " $" + beverage2.cost());
Beverage beverage3 = new HouseBlend();
beverage3 = new Sugar(beverage3);
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
beverage3 new Sugar(beverage3);
beverage3 = new Chocolate(beverage3);
beverage3 = new Cream(beverage3);
System.out.println(beverage3.getDescription() + " $" + beverage3.cost());
}
}
84
Facade Objetivo
Fornece uma interface comum para um grupo de classes de um subsistema, facilitando o seu uso
Motivação Motivação Reduzir o acomplamento entre sistemas
class GOF-FACADE
Subsistema
Class1 Class3 Class5
Class6 Class7
class GOF-FACADE
Subsistema
Cl 3
Class6 Class7
Facade
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
85
Class2Class4
Class1
Class2
Class3
Class4
Class5
10/6/2011
16
FacadeExemplo - UML A facade (TravelFacade) esconde a complexidade para integrar com o sistema
de viagem (TravelSystem)
Facade implementa todo o código necessário para integrar com o sistema
O ideal é definir a fachada como uma interface e então criar sua implementação O ideal é definir a fachada como uma interface e então criar sua implementação concreta class GOF-Facade Sample
T lS t
Trav elFacadeImpl
- hotelBooker: HotelBooker- fl ightBooker: FlightBooker
+ getFlightsAndHotels(Date, Data) : void
Client
+ main(String[]) : void
«interface»
ITravelFacade
+ getFlightsAndHotels(Date, Data) : void
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
86
Trav elSystem
HotelBooker
+ getHotelNamesFor(Date, Date) : ArrayList<Hotel>
FlightBooker
+ getFlightsFor(Date, Date) : ArrayList<Flight>
-fl ightBooker-hotelBooker
FaçadeExemplo - Códigopublic class HotelBooker{
public ArrayList<Hotel> getHotelNamesFor(Date from, Date to) {
//returns hotels available in the particular date range
}}
}
public class FlightBooker{
public ArrayList<Flight> getFlightsFor(Date from, Date to){
//returns flights available in the particular date range
}
}
public interface ITravelFacade {
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
public interface ITravelFacade {
public void getFlightsAndHotels(Date from, Data to);
}
87
10/6/2011
17
FaçadeExemplo - Códigopublic class TravelFacadeImpl implements ITravelFacade{
private HotelBooker hotelBooker;
private FlightBooker flightBooker;
public void getFlightsAndHotels(Date from, Data to) {p g g ( , ) {
ArrayList<Flight> flights = flightBooker.getFlightsFor(from, to);
ArrayList<Hotel> hotels = hotelBooker.getHotelsFor(from, to);
//process and return
}
}
public class Client {
public static void main(String[] args) {
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
public static void main(String[] args) {
TravelFacadeImpl facade = new TravelFacade();
facade.getFlightsAndHotels(from, to);
}
}
88
Bridge Objetivo
Desacoplar a abstração da implementação
Cada um pode ser estendido de forma independente
M ti ã Motivação Quando é possível a presença de mais de uma implementação para uma
determinada abstração
Aplicação Evitar uma ligação forte entre a abstração e a implementação
Permitir que uma implementação seja escolhida em tempo de execução
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
89
10/6/2011
18
BridgeExemplo Abstração (Shape) e implementação (DrawingAPI) podem evoluir de
forma independente
class GOF-Bridge
«interface»
DrawingAPI
+ drawCircle(double, double, double) : void
«interface»
Shape
+ draw() : void+ resizeByPercentage(double) : void
BridgePatternClient
+ main(String[]) : void -drawingAPI
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
90
DrawingAPI1
+ drawCircle(double, double, double) : void
DrawingAPI2
+ drawCircle(double, double, double) : void
CircleShape
- x: double- y: double- radius: double- drawingAPI: DrawingAPI
+ CircleShape(double, double, double, DrawingAPI)+ draw() : void+ resizeByPercentage(double) : void
BridgeExemplo - Código /** "Implementor" */
interface DrawingAPI {
public void drawCircle(double x, double y, double radius);
}}
/** "ConcreteImplementor" 1/2 */
class DrawingAPI1 implements DrawingAPI {
public void drawCircle(double x, double y, double radius) {
System.out.printf("API1.circle at %f:%f radius %f\n", x, y, radius);
}
}
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
/** "ConcreteImplementor" 2/2 */
class DrawingAPI2 implements DrawingAPI {
public void drawCircle(double x, double y, double radius) {
System.out.printf("API2.circle at %f:%f radius %f\n", x, y, radius);
}
}
/** "Abstraction" */
91
10/6/2011
19
BridgeExemplo - Código/** "Implementor" */
interface DrawingAPI {
public void drawCircle(double x, double y, double radius);
}}
/** "ConcreteImplementor" 1/2 */
class DrawingAPI1 implements DrawingAPI {
public void drawCircle(double x, double y, double radius) {
System.out.printf("API1.circle at %f:%f radius %f\n", x, y, radius);
}
}
/** "ConcreteImplementor" 2/2 */
class DrawingAPI2 implements DrawingAPI {
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
class DrawingAPI2 implements DrawingAPI {
public void drawCircle(double x, double y, double radius) {
System.out.printf("API2.circle at %f:%f radius %f\n", x, y, radius);
}
}
92
BridgeExemplo - Códigointerface Shape {/** "Abstraction" */
public void draw(); // low-level
public void resizeByPercentage(double pct); // high-level
}}
class CircleShape implements Shape {/** "Refined Abstraction" */
private double x, y, radius;
private DrawingAPI drawingAPI;
public CircleShape(double x, double y, double radius, DrawingAPI drawingAPI) {
this.x = x; this.y = y; this.radius = radius;
this.drawingAPI = drawingAPI;
}
public void draw() {// low-level i e Implementation specific
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
public void draw() {// low level i.e. Implementation specific
drawingAPI.drawCircle(x, y, radius);
}
public void resizeByPercentage(double pct) {// high-level i.e. Abstraction specific
radius *= pct;
}
}93
10/6/2011
20
BridgeExemplo - Código/** "Client" */
class BridgePatternClient {
public static void main(String[] args) {
Shape[] shapes = new Shape[] {p [] p p [] {
new CircleShape(1, 2, 3, new DrawingAPI1()),
new CircleShape(5, 7, 11, new DrawingAPI2()),
};
for (Shape shape : shapes) {
shape.resizeByPercentage(2.5);
shape.draw();
}
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
}
}
}
94
Composite Objetivo
Compor objetos de forma que partes e estruturas, formadas por estas partes possam ser tratadas de maneira uniforme
Motivação Motivação Em muitas situações objetos podem ser compostos para gerar outros objetos
Caso o código trate as partes e os objetos compostos de forma diferenciada acarretando em uma aplicação mais complexa
Uso Representar hierarquias do tipo “todo-parte” de objetos
Tratar tanto objetos individuais, quanto composições destes objetos de maneira uniforme
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
maneira uniforme
95
10/6/2011
21
CompositeExemplo O diagrama mostra o uso deste padrão de projeto
Um Menu é composto é composto de elementos MenuItem, porém o tratamento do todo (Menu) como das suas partes (MenuItem) será mesmo pois ambos representam herança de MenuComponentpois ambos representam herança de MenuComponent
class GOF-Composite
MenuComponentClient
0..*
é composto
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
96
MenuItem{leaf}
Menu
CompositeExempo Aplicação Gráfica
Uma Ellipse ou um Circle é um elemento gráfico
É possível ter grupos de elementos gráficos que devem ser tratados de maneira uniformemaneira uniforme class GOF-Composite Sample
«interface»
Graphic
+ print() : void
Client
+ main(String[]) : void
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
97
Group
- mChildGraphics: List<Graphic> = new ArrayList<G...
+ print() : void+ add(Graphic) : void+ remove(Graphic) : void
Ellipse{leaf}
+ print() : void
Circle{leaf}
+ print() : void
10/6/2011
22
CompositeExemplo – Códigoimport java.util.List;
import java.util.ArrayList;
interface Graphic {/** "Component" */
//Prints the graphic.g p
public void print();
}
public final class Ellipse implements Graphic {/** "Leaf" */
public void print() {
System.out.println("Ellipse");
}
}
public final class Circle implements Graphic {/** "Leaf" */
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
public final class Circle implements Graphic {/ Leaf /
public void print() {
System.out.println("Circle");
}
}
98
CompositeExemplo – Códigoclass Group implements Graphic {/** "Composite" */
//Collection of child graphics.
private List<Graphic> mChildGraphics = new ArrayList<Graphic>();
public void print() {p p () {
for (Graphic graphic : mChildGraphics) {
graphic.print();
}
}
public void add(Graphic graphic) {//Adds the graphic to the composition.
mChildGraphics.add(graphic);
}
public void remove(Graphic graphic) {//Removes the graphic from the composition
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
public void remove(Graphic graphic) {//Removes the graphic from the composition.
mChildGraphics.remove(graphic);
}
}
99
10/6/2011
23
CompositeExemplo – Códigopublic class Client {/** Client */
public static void main(String[] args) {
Ellipse ellipse1 = new Ellipse(); //Initialize single graphics
Ellipse ellipse2 = new Ellipse();p p p ();
Circle circle1 = new Circle ();
Circle circle2 = new Circle ();
Group = new Group(); //Initialize three composite graphics
Group graphic1 = new Group();
Group graphic2 = new Group();
graphic1.add(ellipse1); //Composes the graphics
graphic1.add(ellipse2);
graphic1 add(circle1);
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
graphic1.add(circle1);
graphic2.add(circle2);
graphic.add(graphic1);
graphic.add(graphic2);
//Prints the complete graphic components
graphic.print();
}
} 100
Proxy Objetivo
Fornece um substituto para um outro objeto permitindo o controle de acesso a este objeto
Motivação Motivação Em muitas situações é necessário controlar o acesso a um objeto a fim de
adiar o custo de sua criação e inicialização
Por exemplo: Um documento que contém várias fotos. Abrir todos os arquivos de forma
simultânea poderia ser ineficiente
O proxy fornece uma representação para a imagem e sua exibição somente ocorrerá no momento em que a página que contiver a respectiva foto seja exibida
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
Uso Proxy Remoto – Oferece uma representação local para um objeto remoto, por
exemplo, em outro espaço de endereçamento
Proxy Virtual – Oferece uma representação para um objeto cuja criação será feita por demanda
Protection Proxy – Controla o acesso a um determinado objeto101
10/6/2011
24
ProxyEstrutura A classe ProxySubject representa a classe Subject. Neste caso o cliente (Client)
utilizará uma instância de ProxySubject e não de subject
A classe ProxySubject pode por exemplo: restringir o acesso ao subject; ser uma representação local; conter um cache para um subject remotorepresentação local; conter um cache para um subject remoto
class GOF-Proxy
Client «interface»ISubject
+ operation() : void
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
102
Subject
+ operation() : void
ProxySubject
- subject: Subject
+ operation() : void
ProxyExemplo A classe ProxyImage representa uma imagem
Neste caso trata-se de um proxy virtual, o cliente do proxy (ProxyClient) não precisa criar objetos da classe RealImage, mas apenas da classe ProxyClient que representará um objeto da classe RealImageque representará um objeto da classe RealImage
class GOF-Proxy
«interface»
Image
+ displayImage() : void
ProxyClient
+ main(String[]) : void
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
103
RealImage
- filename: String
+ RealImage(String)- loadImageFromDisk() : void+ displayImage() : void
ProxyImage
- filename: String- image: RealImage
+ ProxyImage(String)+ displayImage() : void
-image
10/6/2011
25
ProxyExemplo – Códigointerface Image {
void displayImage();
}
class RealImage implements Image {
private String filename;
public RealImage(String filename) {
this.filename = filename;
loadImageFromDisk();
}
private void loadImageFromDisk() {
System out println("Loading " + filename);
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
System.out.println( Loading + filename);
}
public void displayImage() {
System.out.println("Displaying " + filename);
}
}
104
ProxyExemplo – Códigoclass ProxyImage implements Image {
private String filename;
private RealImage image;
public ProxyImage(String filename) { p y g ( g ) {
this.filename = filename;
}
public void displayImage() {
if (image == null) {
image = new RealImage(filename);
}
image.displayImage();
}
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
}
}
105
10/6/2011
26
ProxyExemplo – Códigoclass ProxyClient {
public static void main(String[] args) {
Image image1 = new ProxyImage("HiRes_10MB_Photo1");
Image image2 = new ProxyImage("HiRes 10MB Photo2"); g g y g ( _ _ );
image1.displayImage(); // loading necessary
image2.displayImage(); // loading necessary
image1.displayImage(); // loading unnecessary
}
}
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
106
Padrões Comportamentais Representam e descrevem padrões de comunicação entre objetos a fim de
realizar um comportamento específico
Seu objetivo é que foco do projeto seja a interconexão entre os objetos a fim de obter este comportamentoobter este comportamento
Padrões definidos por Gamma et. al. (GoF) Chain of Responsibility
Command
Flyweigth
Interpreter
Iterator
Mediator
Memento
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
Memento
Observer
State
Strategy
Template
Visitor
107
10/6/2011
27
Padrões Comportamentais Observer
Command
Strategy
Template
Iterator
Visitor
Mediator
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
108
Observer Objetivo
Define uma dependência entre objeto e vários outros(um-para-muitos) sendo que em uma alteração neste objeto, todos os outros são notificados
Motivação Motivação Em muitas situações um objeto pode ter vários outros dependentes.
Neste caso sempre que este objeto (sujeito) for alterado é interessante que outros sejam notificados
Isto porém pode levar a um forte acoplamento entre os mesmos
Uso Quando uma abstração (Classe) possuir dois ou mais aspectos estes podem
ser encapsulados em diferentes classes
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
ser encapsulados em diferentes classes
Em situações onde a alteração de um objeto pode afetar um grupo de outros objetos não conhecidos previamente
Permitir que um objeto seja capaz de notificar outros sem que estejam acoplados
109
10/6/2011
28
ObserverEstrutura O sujeito (subject) é observado por uma lista de observadores (Observer)
Um método notify() invoca o método update() nos observadores class GOF-Observ er
Subject
- observers: List<Observer>
+ attach(Observer) : void+ detach(Observer) : void+ notfiy() : void
Observer
+ update() : void
ConcreteSubject ConcreteObserv er
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
110
ConcreteSubject
- subejctState: Object
+ attach(Observer) : void+ detach(Observer) : void+ notfiy() : void
«property get»+ getSubejctState() : Object
«property set»+ setSubejctState(Object) : void
ConcreteObserv er
- observerState: Object
+ update() : void
ObserverExemplo A medida que as ações de uma empresa (Stock) forem alteradas os
investirores (Inverstor) serão notificados class GOF-Observer
Stock
M i A li ti
- symbol: String- price: double- investors: List<IInvestor> = new List<IInves...
+ Stock(String, double)+ attach(IInvestor) : void+ detach(IInvestor) : void+ notify() : void+ getPrice() : double+ setPrice(double) : void+ getSymbol() : String
Petrobras
«interface»
IInvestor
+ update(Stock) : void
-stock
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
111
MainApplication
+ Main() : void
Petrobras
+ Petrobras(String, double)Inv estor
- name: String- stock: Stock
+ Investor(String)+ update(Stock) : void+ getStock() : Stock+ setStock(Stock) : void
10/6/2011
29
ObserverExemplo - Código/// MainApp startup class for Real-World
public class MainApplication {
public static void Main(){
// Create Petrobras stock and attach investors
Petrobras petro = new Petrobras("Petrobras", 120.00);
petro.attach(new Investor("Sorros"));
petro.attach(new Investor("Berkshire"));
// Fluctuating prices will notify investors
petro.setPrice(120.10);
petro.setPrice(121.00);
petro setPrice(120 50);
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
petro.setPrice(120.50);
petro.setPrice(120.75);
}
}
112
ObserverExemplo - Código/// The 'Subject' abstract class
public abstract class Stock {
private String symbol; private double price;
private List<IInvestor> investors = new List<IInvestor>();p ();
public Stock(String symbol, double price){
this.symbol = symbol;
this.price = price;
}
public void attach(IInvestor investor){ investors.add(investor); }
public void detach(IInvestor investor){ investors.remove(investor); }
public void notify() {
for (IInvestor investor : investors){
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
for (IInvestor investor : investors){
investor.update(this); }
System.out.println("");
}
113
10/6/2011
30
ObserverExemplo - Código
public double getPrice(){ return price; }
public void setPrice(double nprice){
if (price != nprice){
price = nprice;p p ;
notify();
}
}
// Gets the symbol
public String getSymbol(){
return symbol;
}
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
114
ObserverExemplo - Código// The 'ConcreteSubject' class
public class Petrobras extends Stock
{
// Constructor
public Petrobras(String symbol, double price) {
super(symbol, price)
}
}
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
115
10/6/2011
31
ObserverExemplo - Código// The 'Observer' interface
interface Iinvestor {
void update(Stock stock);
}}
// The 'ConcreteObserver' class
public class Investor implements IInvestor {
private String name;
private Stock stock;
public Investor(String name){ this.name = name; }
public void update(Stock stock){
System out println("Notificando " + this name + "que " + stock getSymbol() + " alterou para
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
System.out.println( Notificando + this.name + que + stock.getSymbol() + alterou para " + stock.getPrice();
}
public Stock getStock() { return stock; }
public void setStock(Stock value){ stock = value; }
}
116
Command Objetivo
Motivação
Uso
Estrutura
Exemplo Código
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
117
10/6/2011
32
CommandExemplo - Estrutura
class GOF-Command
«interface»
Command
+ execute() : void-fl ipDownCommand
-flipUpCommand
Switch
- flipUpCommand: Command- flipDownCommand: Command
+ Switch(Command, Command)+ flipUp() : void+ flipDown() : void FlipUpCommand
- theLight: Light
+ FlipUpCommand(Light)+ execute() : void
FlipDownCommand
- theLight: Light
+ FlipDownCommand(Light)+ execute() : void
PressSwitch
+ main(String[]) : void
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
118
Light
+ Light()+ turnOn() : void+ turnOff() : void
-theLight-theLight
CommandCódigo/* The Invoker class */
public class Switch {
private Command flipUpCommand;
private Command flipDownCommand;p p ;
public Switch(Command flipUpCmd, Command flipDownCmd) {
this.flipUpCommand = flipUpCmd;
this.flipDownCommand = flipDownCmd;
}
public void flipUp() {
flipUpCommand.execute();
}
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
public void flipDown() {
flipDownCommand.execute();
}
}
119
10/6/2011
33
CommandCódigo/* The Receiver class */
public class Light {
public Light() { }
public void turnOn() {p () {
System.out.println("The light is on");
}
public void turnOff() {
System.out.println("The light is off");
}
}
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
120
CommandCódigo/* The Command interface */
public interface Command {
void execute();
}}
/* The Command for turning the light on in North America, or turning the light off in most other places */
public class FlipUpCommand implements Command {
private Light theLight;
public FlipUpCommand(Light light) {
this.theLight = light;
}
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
}
public void execute(){
theLight.turnOn();
}
}
121
10/6/2011
34
CommandCódigo/* The Command for turning the light off in North America, or turning the light on in most other
places */
public class FlipDownCommand implements Command {
private Light theLight;
public FlipDownCommand(Light light) {
this.theLight = light;
}
public void execute() {
theLight.turnOff();
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
g ();
}
}
122
CommandCódigopublic class PressSwitch { // The test class or client
public static void main(String[] args) {
Light lamp = new Light();
Command switchUp = new FlipUpCommand(lamp);p p p ( p);
Command switchDown = new FlipDownCommand(lamp);
Switch s = new Switch(switchUp, switchDown);
try {
if (args[0].equalsIgnoreCase("ON")) {
s.flipUp();
} else if (args[0].equalsIgnoreCase("OFF")) {
s.flipDown();
} else {
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
} else {
System.out.println("Argument \"ON\" or \"OFF\" is required.");
}
} catch (Exception e) {
System.out.println("Arguments required.");
}
}
} 123
10/6/2011
35
CommandCódigo/* The Invoker class */
public class Switch {
private Command flipUpCommand;p p p ;
private Command flipDownCommand;
public Switch(Command flipUpCmd, Command flipDownCmd) {
this.flipUpCommand = flipUpCmd;
this.flipDownCommand = flipDownCmd;
}
public void flipUp() {
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
public void flipUp() {
flipUpCommand.execute();
}
public void flipDown() {
flipDownCommand.execute();
}
} 124
Strategy Objetivo
Definir uma família de algoritmos que podem ser intercambiáveis sendo possível alterar os algoritmos sem alterar o cliente que os utiliza
Motivaçãoç Considere a existência de vários algoritmos para uma mesma tarefa, por exemplo,
ordenar uma lista de objetos
Uma aplicação que deve suportar diferentes algoritmos pode tornar-se complexa e no geral não permite a adição de novos que possam ser desenvolvidos
Uso Configurar o uso considerando que existem classes relacionadas com diferentes
comportamentos
Existência de diferentes algoritmos ou métodos que podem ser implementados e que
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
devem ser selecionados em tempo de execução
Impedir que o cliente tenha que manter dados específicos para diferentes algoritmos
Remover o uso de estruturas de seleção, como um switch, em uma operação. Neste caso cada possibilidade de código a ser executado se transforma em uma diferente estratégia
125
10/6/2011
36
StrategyEstrutura Um mesma mesma estratégia (Strategy) pode ser implementada de diversas
formas (AConcreteStategy, BConcreteStategy, CConcreteStategy)
Em um contexto (Context) contém uma estratégia genérica
O contexto é utlizado por um cliente (Client) Uma alteração no contexto pode O contexto é utlizado por um cliente (Client). Uma alteração no contexto pode indicar o uso de uma nova estratégia
class GOF-Strategy
«interface»Strategy
+ callAlgorithm() : void
Context
- strategy: Strategy
Client
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
126
AConcreteStrategy
+ callAlgorithm() : void
BConcreteStrategy
+ callAlgorithm() : void
CConcreteStrategy
+ callAlgorithm() : void
StrategyExemplo Neste caso a estratégia permite que o cliente (StrategyExample) utilize
diferentes operações aritméticas conforme o contexto (Context) utilizado
class GOF Strategy Sample class GOF-Strategy Sample
«interface»
Strategy
+ execute(int, int) : int
Context
- strategy: Strategy
+ Context(Strategy)+ executeStrategy(int, int) : int
-strategy
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
127
ConcreteStrategyAdd
+ execute(int, int) : int
ConcreteStrategySubtract
+ execute(int, int) : int
ConcreteStrategyMultiply
+ execute(int, int) : intStrategyExample
+ main(String[]) : void
10/6/2011
37
StrategyExemplo - Códigointerface Strategy {
int execute(int a, int b);
}
class ConcreteStrategyAdd implements Strategy {gy p gy {
public int execute(int a, int b) {
System.out.println("Called ConcreteStrategyAdd's execute()");
return a + b; }
}
class ConcreteStrategySubtract implements Strategy {
public int execute(int a, int b) {
System.out.println("Called ConcreteStrategySubtract's execute()");
return a - b; }
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
return a b; }
}
class ConcreteStrategyMultiply implements Strategy {
public int execute(int a, int b) {
System.out.println("Called ConcreteStrategyMultiply's execute()");
return a * b; }
}128
StrategyExemplo - Códigoclass Context {
private Strategy strategy;
// Constructor
public Context(Strategy strategy) { p ( gy gy) {
this.strategy = strategy; }
public int executeStrategy(int a, int b) {
return strategy.execute(a, b); }
}
class StrategyExample {
public static void main(String[] args) {
Context context;
context = new Context(new ConcreteStrategyAdd());
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
context new Context(new ConcreteStrategyAdd());
int resultA = context.executeStrategy(3,4);
context = new Context(new ConcreteStrategySubtract());
int resultB = context.executeStrategy(3,4);
context = new Context(new ConcreteStrategyMultiply());
int resultC = context.executeStrategy(3,4);
}
} 129
10/6/2011
38
Template
Objetivo Define um modelo (template) de um algoritmo em deixando alguns passos
para suas subclasses
Motivação Motivação
Uso Implementar as partes invariantes de um algoritmo na superclasse, deixando
para a subclasse o comportamento que pode variar
Evitar a duplicação de código, localizado o comportamento comum na superclasse
Estrutura
E l Códi
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
Exemplo Código
130
TemplateEstrutura A classe abstrata (AbstractClass) possui um conjunto de operações e um
método (templateMethod) que é responsável por invocar as operaçoes que são especializadas nas subclasses (ConcreteClass1 e ConcreteClass2)ConcreteClass2)
class GOF-Template
AbstractClass
+ templateMethod() : void+ baseOperation() : void+ primitiveOperation1() : void+ primitiveOperation2() : void
templateMethod(){ ... baseOperation(); ... primitiveOperation1(); ... primitiveOperation2();}
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
131
ConcreteClass1
+ primitiveOperation1() : void+ primitiveOperation2() : void
ConcreteClass2
+ primitiveOperation1() : void+ primitiveOperation2() : void
10/6/2011
39
TemplateExemplo Um jogo contém operações básicas que serão especializadas
O template method aqui é playOneGame()
class GOF Template class GOF-Template
Game
# playersCount: int
+ initial izeGame() : void+ makePlay(int) : void+ endOfGame() : boolean+ printWinner() : void+ playOneGame(int) : void
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
132
Monopoly
+ initial izeGame() : void+ makePlay(int) : void+ endOfGame() : boolean+ printWinner() : void
Chess
+ initializeGame() : void+ makePlay(int) : void+ endOfGame() : boolean+ printWinner() : void
TemplateExemplo – Código
public abstract class Game {
protected int playersCount;
public abstract void initializeGame();
public abstract void makePlay(int player);p y( p y );
public abstract boolean endOfGame();
public abstract void printWinner();
/* A template method : */
public final void playOneGame(int playersCount) {
this.playersCount = playersCount;
initializeGame();
int j = 0;
while (!endOfGame()) {
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
while (!endOfGame()) {
makePlay(j);
j = (j + 1) % playersCount;
}
printWinner();
}
}133
10/6/2011
40
TemplateExemplo – Código//Now we can extend this to implement other games
public class Monopoly extends Game {
/* Implementation of necessary concrete methods */
public void initializeGame() {p () {
// Initialize players
// Initialize money
}
public void makePlay(int player) {
// Process one turn of player
}
public boolean endOfGame() {
// Return true if game is over
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
// Return true if game is over
// according to Monopoly rules
}
public void printWinner() {
// Display who won
}
}134
TemplateExemplo – Códigopublic class Chess extends Game {
/* Implementation of necessary concrete methods */
public void initializeGame() {
// Initialize playersp y
// Put the pieces on the board
}
public void makePlay(int player) {
// Process a turn for the player
}
public boolean endOfGame() {
// Return true if in Checkmate or
// Stalemate has been reached
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
// Stalemate has been reached
}
public void printWinner() {
// Display the winning player
}
}
135
10/6/2011
41
TemplateExemplo – Códigopublic class Monopoly extends Game {
/* Implementation of necessary concrete methods */
public void initializeGame() {
// Initialize playersp y
// Initialize money
}
public void makePlay(int player) {
// Process one turn of player
}
public boolean endOfGame() {
// Return true if game is over
// according to Monopoly rules
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
// according to Monopoly rules
}
public void printWinner() {
// Display who won
}
}
136
Iterator
Objetivo Fornece uma maneira de acessar os componentes de um objeto sem expor a
sua representação interna
Motivação Motivação
Uso
Estrutura
Exemplo Código
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
137
10/6/2011
42
IteratorEstrutura O iterator (ListIterator) permite o acesso ao objeto da lista em que seja
necessário conhecer o seu interior
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
138
IteratorExemplo Em uma televisão (ConcreteTV) existe um Iterator (ChannelIterator) sobre os canais desta
televisão
Idepentende de como o acesso aos canais é feito é possível obtê-los através do Iterator
class GOF-Iterator
«interface»
Iterator
+ hasNext() : boolean+ next() : void+ currentItem() : String
«interface»
TV
+ getIterator() : ChannelIterator
ChannelIterator
- channels: List<String>- currentPos: int = 0
+ ChannelIterator(List<String>)+ hasNext() : boolean+ next() : void+ currentItem() : String
-iterator
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
139
ConcreteTV
- iterator: ChannelIterator- channels: List<String>
+ ConcreteTV()+ getIterator() : ChannelIterator
10/6/2011
43
IteratorCódigo//Iterator interface
public interface Iterator {
public boolean hasNext();
public void next();p ();
public String currentItem();
}
//Aggregate interface
public interface TV {
public ChannelIterator getIterator();
//other TV methods
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
//other TV methods
}
140
IteratorCódigo//Concrete Aggregator
public class ConcreteTV implements TV{
private ChannelIterator iterator;
private List<String> channels; p g ;
public ConcreteTV() {
iterator = new ConcreteChannelIterator(channels);
}
public ChannelIterator getIterator() {
return iterator;
}
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
}
}
141
10/6/2011
44
IteratorCódigo//Concrete Iterator
public class ChannelIterator implements Iterator {
private List<String> channels;
private int currentPos = 0; p ;
public ChannelIterator(List<String> channels){
this.channels = channels;
}
public boolean hasNext(){
if(currentPos + 1 < channels.size()){
return true;
}
return false;
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
return false;
}
public void next() { currentPos++; }
public String currentItem() { return channels.get(currentPos);
}
}142
Visitor
Objetivo Permite que uma ou mais operações seja aplicada a um conjunto ou estrutura de
objetos, desacoplando as operações desta estrutura
A operação “visita” o conjunto de objetos e é executada sobre o mesmop ç j j
Motivação Para calcular o total de uma compra, diferentes operações devem ser executadas
sobre o produto. Em alguns caso é necessário pesar o produto para obter seu preço, em outros é necessário apenas ler seu código de barras, em outro finalmente é aplicado um desconto por compras em quantidade
Ao passar no caixa, o atendente será o Visitor, que irá obter um produto e então calculará o seu preço.
Uso
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
Desacoplar a lógica de uma operação dos objetos que são submetidos a esta o operação
Permitir que operações diferentes e não relacionadas seja aplicadas em uma estrutura de objetos
143
10/6/2011
45
VisitorEstrutura A interface Visitor define uma operação sobre um elemento (ConcreteElement).
Um elemento por sua vez possui uma operação que permite aceitar um visitante (accept), associando-se ao vistante
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
144
VisitorEstrutura
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
145
10/6/2011
46
VisitorEstrutura
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
146
VisitorExemplo Utilizando um visitor (PostageVisitor) será possível implementar o cálculo do frente para
diferentes produtos (Book, CD, DVD) e então calcular o valor do frete (calculatePostage) class GOF - Visitor
ShoppingCart
- items: ArrayList<Visitable>
«interface»
Visitable
+ accept(Visitor) : void
«interface»
Visitor
+ visit(Book) : void+ visit(CD) : void+ visit(DVD) : void
PostageVisitor
- totalPostageForCart: double
+ visit(Book) : void+ visit(CD) : void+ visit(DVD) : void+ getTotalPostage() : double
- items: ArrayList<Visitable>
+ calculatePostage() : double
Element
+ accept(Visitor) : void
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
147
Book
- price: double- weight: double
+ getPrice() : double+ getWeight() : double
CD DVD
10/6/2011
47
VisitorExemplo - Código//Element interface
public interface Visitable {
public void accept(Visitor visitor);
}}
//abstract element
public abstract class Element implements Visitable {
//accept the visitor
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
//concrete element
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
//concrete element
public class CD extends Element{
}
//concrete element
public class DVD extends Element{
}
148
VisitorExemplo - Código//concrete element
public class Book extends Element {
private double price;
private double weight;p g ;
public double getPrice()
{
return price;
}
public double getWeight()
{
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
{
return weight;
}
}
149
10/6/2011
48
VisitorExemplo - Códigopublic interface Visitor {
public void visit(Book book);
//visit other concrete items
public void visit(CD cd);p ( );
public void visit(DVD dvd);
}
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
150
VisitorExemplo - Códigopublic class PostageVisitor implements Visitor {
private double totalPostageForCart;
//collect data about the book
public void visit(Book book) {p ( ) {
//assume we have a calculation here related to weight and price
//free postage for a book over 10
if(book.getPrice() < 10.0) {
totalPostageForCart += book.getWeight() * 2;
}
}
//add other visitors here
public void visit(CD cd){ }
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
public void visit(CD cd){...}
public void visit(DVD dvd){...}
//return the internal state
public double getTotalPostage() {
return totalPostageForCart;
}
} 151
10/6/2011
49
VisitorExemplo - Códigopublic class ShoppingCart {
//normal shopping cart stuff
private ArrayList<Visitable> items;
public double calculatePostage() {p g () {
//create a visitor
PostageVisitor visitor = new PostageVisitor();
//iterate through all items
for(Visitable item: items) {
item.accept(visitor);
}
double postage = visitor.getTotalPostage();
return postage;
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
return postage;
}
}
152
Mediator Objetivo
Permite criar um baixo acoplamento entre um conjunto de objetos que se comunica e interage
O mediator é o objeto que realiza a comunicação com cada objeto permitindo O mediator é o objeto que realiza a comunicação com cada objeto permitindo que esta comunicação entre estes objetos ocorra de forma independende uma das outras
Motivação Uma torre de controle em um aeroporto é o mediator entre os aviões e o
aeroporto
Ao invés dos aviões comunicarem entre si cada um comunica diretamente com a torre
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
Uso Quando existe uma comunicação complexa, porém bem definida, entre
objetos
Em situações onde existem vários relacionamentos entres objetos produzindo uma diagrama de classes que indica alto acoplamento
153
10/6/2011
50
MediatorEstrutura O mediator define uma interface para a comunicação entre diferentes
partes (Colleage). Um mediator é então criado (ConcreteMediator) a fim de implementar o comportamento para a comunicação
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
154
MediatorExemplo A comunicação entre as entidades (FixedEntity e MobileEntity) é realizada
através do mediator (ApplicationMediator) associado a cada entidade class GOF - Mediator
«interface»
Mediator
+ send(String, Entity) : void
Entity
- mediator: Mediator
+ Entity(Mediator)+ send(String) : void+ getMediator() : Mediator+ receive(String) : void
ApplicationMediator
- entitys: ArrayList<Entity>
+ ApplicationMediator()FixedEntity
MobileEntity
+ receive(String) : void
Client
+ main(String[]) : void
-mediator
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
155
pp ()+ addEntity(Entity) : void+ send(String, Entity) : void
+ receive(String) : void
10/6/2011
51
MediatorCódigo//Mediator interface
public interface Mediator {
public void send(String message, Entity entity);
}}
public abstract class Entity {//Entity Abstract Base Class
private Mediator mediator;
public Entity(Mediator m){
mediator = m;
}
public void send(String message){ //send a message via the mediator
mediator.send(message, this);
}
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
}
public Mediator getMediator(){ //get access to the mediator
return mediator;
}
public abstract void receive(String message);
}156
MediatorCódigopublic class ApplicationMediator implements Mediator {
private ArrayList<Entity> entitys;
public ApplicationMediator(){
entitys = new ArrayList<Entity>();y y y ();
}
public void addEntity(Entity entity) {
entitys.add(entity);
}
public void send(String message, Entity originator) {
//let all other screens know that this screen has changed
for(Entity entity: entitys){
//don't tell ourselves
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
//don t tell ourselves
if(entity != originator){
entity.receive(message);
}
}
}
} 157
10/6/2011
52
MediatorCódigopublic class FixedEntity extends Entity {
public void receive(String message){
System.out.println("FixedEntity Received: " + message);
}}
}
public class MobileEntity extends Entity {
public void receive(String message) {
System.out.println("MobileEntity Received: " + message);
}
}
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
158
MediatorCódigo//Client shows the use
public class Client {
public static void main(String[] args) {
ApplicationMediator mediator = new ApplicationMediator(); pp pp ();
FixedEntity desktop = new FixedEntity(mediator)
FixedEntity mobile = new MobileEntity(mediator)
mediator.addEntity(desktop);
mediator.addEntity(mobile);
desktop send("Hello World");
Programação Orientada a Objetos 2Flávio de Oliveira Silva, M.Sc.
desktop.send( Hello World );
mobile.send("Hello");
}
}
159