10/6/2011
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 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
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
56
Classificação de Padrões Padrõ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)
Padrões de Arquitetura (Architectural patterns)
Seu foco é na arquitetura do software
Padrões de Projeto (Design 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
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 Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
57
1
10/6/2011
Classificação de Padrões Padrões
Padrões de Análise (Analysis patterns)
Padrões de Arquitetura (Architectural patterns)
Martin Fowler , 1996 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 .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 Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
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 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 Quando atributos possuam um comportamento relacionado Q d múltipos úl i ib l i d e presente em muitos tipos, combine estes atributos em um novo tipo fundamental
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
59
2
10/6/2011
Padrões de Análise (Analysis Patterns)
Exemplos de alguns padrões de projeto
Quantity (3.1) Conversion Ratio (3.2) C dU 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) Summary Account (6.3) S A (6 3) Plan (8.4) Contract (9.1) Product (10.3) Associative Type (15.1) Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
60
Padrões de Projeto GoF
Trabalho proposto inicialmente por Erich Gamma, Richard Helm, Ralph Jonhson, John Vlissides (Gang of Four) em 1995 Famílias de Padrões
D C i ã De Criação
Estruturais
Responsáveis pela criação de objetos Permitem que o sistema fique independente da forma como os objetos são criados 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 Descrevem a comunicação entre objetos
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
61
3
10/6/2011
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
Singleton
Garante que apenas uma classe possua uma única instância e oferece um acesso global à mesma
Builder
Fornecem uma interface para criação de objetos sem especificar sua classe concreta
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
Permite que um objeto seja criado a partir de uma instância existente copiando suas propriedades
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
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» ImageReaderFactory
ImageReader +
getDecodedImage() : DecodedImage
GifReader +
getDecodedImage() : DecodedImage
+
getImageReader(InputStream) : ImageReader
JpegReader +
getDecodedImage() : DecodedImage
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
63
4
10/6/2011
Factory Exemplo public interface ImageReader { public DecodedImage getDecodedImage(); } public class GifReader implements ImageReader { public DecodedImage getDecodedImage() { // ... return decodedImage; } } public class JpegReader implements ImageReader { public DecodedImage getDecodedImage() { // ... return decodedImage; } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
64
Factory Exemplo public 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 2 Flávio de Oliveira Silva, M.Sc.
65
5
10/6/2011
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 ApplicationRunner + +
main(String[]) : void createOsSpecificFactory() : GUIFactory
Application +
Application(GUIFactory)
«interface»
«interface»
GUIFactory +
Button
createButton() : Button
WinFactory +
+
OSXFactory
createButton() : Button
+
createButton() : Button
paint() : void
WinButton +
paint() : void
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
OSXButton +
paint() : void
66
Abstract Factory interface GUIFactory { public Button createButton(); } class WinFactory GUIFactory y implements p y{ public Button createButton() { return new WinButton(); } } class OSXFactory implements GUIFactory { public Button createButton() { return new OSXButton(); } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
67
6
10/6/2011
Abstract Factory interface Button { public void paint(); } class WinButton implements Button { bli void id paint() i t() { public 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 2 Flávio de Oliveira Silva, M.Sc.
68
Abstract Factory class 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() { int i t sys = readFromConfigFile("OS_TYPE"); dF C fi Fil ("OS TYPE") if (sys == 0) { return new WinFactory(); } else { return new OSXFactory(); } } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
69
7
10/6/2011
Singleton
Objetivo
Garante que existirá uma única instância de um objeto de uma classe e permite um acesso global ao mesmo
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 2 Flávio de Oliveira Silva, M.Sc.
70
Singleton Exemplo public class Singleton { //instância de um objeto da classe Singleton //inicializada com a chamada do construtor private static Singleton instance = new Singleton(); //Construtor privado impede criação de objetos desta classe private Singleton() { //lógica para criação do objeto } //método que retorna a ú única instância da classe // ét d estático táti t i i tâ i d l public static Singleton getInstance() { return instance; } } Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
71
8
10/6/2011
Singleton Exemplo - 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 { public = new Singleton(); bli static t ti final fi l Singleton Si l t instance i t Si l t () } public static Singleton getInstance() { return SingletonHolder.instance; } Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
72
Padrões Estruturais
Adapter Bridge Composite Decorator Facade Proxy
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
73
9
10/6/2011
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 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 p ç q possui serviços que serão utilizados,, p porém não na Interface necessária Por exemplo, uma classe que espera valores boleanos
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
74
Adapter Exemplo
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 (BinaryCalculator), porém adatapada o class GOF-Adapter «interface» ICalculator +
add(int, int) : int
CalculatorAdapter -
BinaryCalculator
bcalc: BinaryCalculator +
+ +
add(String, String) : string
CalculatorAdapter(bcalc) add(int, int) : int
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
75
10
10/6/2011
Adapter Exemplo public 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; } 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(); } Programação Orientada a Objetos 2 } Flávio de Oliveira Silva, M.Sc.
76
Adapter Outro Exemplo
Dois exemplos de classes adptadoras. Uma baseada em uso (DListToStackAdapter) e outra em herança múltipla (DListStackAdapter) class GOF-Adapter p T «interface»
DList
Stack + + +
+ + + + + + + +
push(T) : void pop() : T top() : T
insert(DNode, T) : void remove(DNode, T) : void insertHead(T) : void insertTail(T) : void removeHead() : T removeTail() : T getHead() : T getTail() : T
T
T
p DListStackAdapter
DListToStackAdapter -
m_List: DList
+ + + +
DListToStackAdapter(DList) push(T) : void pop() : T top() : T
+ + +
push(T) : void pop() : T top() : T
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
77
11
10/6/2011
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 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 cada opção não é melhor alternativa Neste caso o Decorator pode ser uma opção para a modelagem
Programação Orientada a Objetos 2
78
Flávio de Oliveira Silva, M.Sc.
Decorator Exemplo 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)
class l GOF-Decorator GOF D t
Beverage
StarbuzzCoffee # +
CondimentDecorator
description: String = "Unknown Beverage" +
main(String[]) : void + +
getDescription() : String
getDescription() : String cost() : double
DarkRoast + +
DarkRoast() cost() : double
Cream Milk HouseBlend
Decaf + +
Decaf() cost() : double
Espresso + +
Espresso() cost() : double
+ +
HouseBlend() cost() : double
-
beverage: Beverage
+ + +
Milk(Beverage) getDescription() : String cost() : double
-
beverage: Beverage
+ + +
Cream(Beverage) getDescription() : String cost() : double
Chocolate -
beverage: Beverage
+ + +
Chocolate(Beverage) getDescription() : String cost() : double
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
Sugar -
beverage: Beverage
+ + +
Sugar(Beverage) getDescription() : String cost() : double
79
12
10/6/2011
Decorator Exemplo - Código public 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 2 Flávio de Oliveira Silva, M.Sc.
80
Decorator Exemplo - Código public 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 1.99; 99; } } public class HouseBlend extends Beverage { public HouseBlend() { description = "House Blend Coffee"; } public double cost() { return .89; } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
81
13
10/6/2011
Decorator Exemplo - Código public class Milk extends CondimentDecorator { private Beverage beverage; public Milk(Beverage beverage) { this.beverage = beverage; } public String getDescription() p gg p () {{return beverage.getDescription() g g p () + ",, Milk";; } 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(); } } 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(); } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
82
Decorator Exemplo - Código public class Cream extends CondimentDecorator { private Beverage beverage; public Cream(Beverage p ( g beverage) g ){ this.beverage = beverage; } public String getDescription() { return beverage.getDescription() + ", Cream"; } public double cost() { return .10 + beverage.cost(); } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
83
14
10/6/2011
Decorator Exemplo - Código public 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); beverage3 = new Chocolate(beverage3); beverage3 = new Cream(beverage3); System.out.println(beverage3.getDescription() + " $" + beverage3.cost()); } }
Programação Orientada a Objetos 2
84
Flávio de Oliveira Silva, M.Sc.
Facade
Objetivo
Fornece uma interface comum para um grupo de classes de um subsistema, facilitando o seu uso
Motivação
Reduzir o acomplamento entre sistemas class GOF-FACADE
class GOF-FACADE
Class6
Class6
Class7
Class7
Facade Subsistema
Subsistema
Class3
Class1
Class5
Cl Class3 3
Class1
Class4
Class2
Class4
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
Class5
Class2
85
15
10/6/2011
Facade Exemplo - 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 concreta class GOF-Facade Sample
«interface» ITravelFacade +
Trav elFacadeImpl
Client +
getFlightsAndHotels(Date, Data) : void
main(String[]) : void
-
hotelBooker: HotelBooker flightBooker: FlightBooker
+
getFlightsAndHotels(Date, Data) : void
T Trav elSystem lS t -flightBooker
-hotelBooker
FlightBooker +
getFlightsFor(Date, Date) : ArrayList
HotelBooker +
getHotelNamesFor(Date, Date) : ArrayList
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
86
Façade Exemplo - Código public class HotelBooker{ public ArrayList getHotelNamesFor(Date from, Date to) { //returns hotels available in the particular date range } } public class FlightBooker{ public ArrayList getFlightsFor(Date from, Date to){ //returns flights available in the particular date range } } public interface ITravelFacade { public void getFlightsAndHotels(Date from, Data to); }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
87
16
10/6/2011
Façade Exemplo - Código public class TravelFacadeImpl implements ITravelFacade{ private HotelBooker hotelBooker; private FlightBooker flightBooker; public void g getFlightsAndHotels(Date from,, Data to)) p g ( { ArrayList flights = flightBooker.getFlightsFor(from, to); ArrayList hotels = hotelBooker.getHotelsFor(from, to); //process and return } } public class Client { public static void main(String[] args) { TravelFacadeImpl facade = new TravelFacade(); facade.getFlightsAndHotels(from, to); } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
88
Bridge
Objetivo
M ti ã Motivação
Desacoplar a abstração da implementação Cada um pode ser estendido de forma independente 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 2 Flávio de Oliveira Silva, M.Sc.
89
17
10/6/2011
Bridge Exemplo Abstração (Shape) e implementação (DrawingAPI) podem evoluir de forma independente
class GOF-Bridge «interface»
BridgePatternClient +
«interface»
Shape
main(String[]) : void
+ +
DrawingAPI
draw() : void resizeByPercentage(double) : void
-drawingAPI +
drawCircle(double, double, double) : void
CircleShape -
x: double y: double radius: double drawingAPI: DrawingAPI
+ + +
CircleShape(double, double, double, DrawingAPI) draw() : void resizeByPercentage(double) : void
Draw ingAPI1
Draw ingAPI2 +
drawCircle(double, double, double) : void
+
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
drawCircle(double, double, double) : void
90
Bridge Exemplo - 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 { public void drawCircle(double x, double y, double radius) { System.out.printf("API2.circle at %f:%f radius %f\n", x, y, radius); } }
Programação Orientada a Objetos 2
/** "Abstraction" */
Flávio de Oliveira Silva, M.Sc.
91
18
10/6/2011
Bridge Exemplo - 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 { public void drawCircle(double x, double y, double radius) { System.out.printf("API2.circle at %f:%f radius %f\n", x, y, radius); } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
92
Bridge Exemplo - Código interface 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 ii.e. low-level e Implementation specific drawingAPI.drawCircle(x, y, radius); } public void resizeByPercentage(double pct) {// high-level i.e. Abstraction specific radius *= pct; } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
93
19
10/6/2011
Bridge Exemplo - Código /** "Client" */ class BridgePatternClient { public static void main(String[] args) { Shape[] p [] shapes p = new Shape[] 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 2 Flá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
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 2 Flávio de Oliveira Silva, M.Sc.
95
20
10/6/2011
Composite Exemplo
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 MenuComponent class GOF-Composite
Client MenuComponent 0..*
é composto
MenuItem {leaf}
Menu
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
96
Composite Exempo
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 uniforme class GOF-Composite Sample «interface» Client +
Graphic +
main(String[]) : void
Ellipse {leaf} +
print() : void
print() : void
Circle
Group {leaf}
+
print() : void
-
mChildGraphics: List = new ArrayList
+ + +
print() : void add(Graphic) : void remove(Graphic) : void
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
97
21
10/6/2011
Composite Exemplo – Código import 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" Leaf *// public void print() { System.out.println("Circle"); } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
98
Composite Exemplo – Código class Group implements Graphic {/** "Composite" */ //Collection of child graphics. private List mChildGraphics = new ArrayList(); public void p print() 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. composition mChildGraphics.remove(graphic); } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
99
22
10/6/2011
Composite Exemplo – Código public class Client {/** Client */ public static void main(String[] args) { Ellipse ellipse1 = new Ellipse(); //Initialize single graphics Ellipse = new Ellipse(); p ellipse2 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); graphic1 add(circle1); graphic2.add(circle2); graphic.add(graphic1); graphic.add(graphic2); //Prints the complete graphic components graphic.print(); } Programação Orientada a Objetos 2 } Flávio de Oliveira Silva, M.Sc.
100
Proxy
Objetivo
Fornece um substituto para um outro objeto permitindo o controle de acesso a este objeto
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
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 objeto Programação Orientada a Objetos 2 101 Flávio de Oliveira Silva, M.Sc.
23
10/6/2011
Proxy Estrutura
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 remoto class GOF-Proxy
«interface» ISubj ect
Client
+
operation() : void
ProxySubj ect
Subj ect
-
subject: Subject
+
operation() : void
+
operation() : void
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
102
Proxy Exemplo
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 RealImage class GOF-Proxy «interface» ProxyClient +
main(String[]) : void
-
filename: String image: RealImage
+ +
ProxyImage(String) displayImage() : void
Image +
displayImage() : void
RealImage
ProxyImage -image
-
filename: String
+ +
RealImage(String) loadImageFromDisk() : void displayImage() : void
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
103
24
10/6/2011
Proxy Exemplo – Código interface 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); System out println("Loading } public void displayImage() { System.out.println("Displaying " + filename); } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
104
Proxy Exemplo – Código class ProxyImage implements Image { private String filename; private RealImage image; public ProxyImage(String p y g ( g filename)) { this.filename = filename; } public void displayImage() { if (image == null) { image = new RealImage(filename); } image.displayImage(); } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
105
25
10/6/2011
Proxy Exemplo – Código class ProxyClient { public static void main(String[] args) { Image image1 = new ProxyImage("HiRes_10MB_Photo1"); Image g image2 g = new ProxyImage("HiRes y g ( _10MB_Photo2"); ); image1.displayImage(); // loading necessary image2.displayImage(); // loading necessary image1.displayImage(); // loading unnecessary } }
Programação Orientada a Objetos 2 Flá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 comportamento Padrões definidos por Gamma et. al. (GoF)
Chain of Responsibility Command Flyweigth Interpreter Iterator Mediator Memento Observer State Strategy Template Visitor
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
107
26
10/6/2011
Padrões Comportamentais
Observer Command Strategy Template Iterator Visitor Mediator
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
108
Observer
Objetivo
Motivação
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 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 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 Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
109
27
10/6/2011
Observer Estrutura
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
Observer
-
observers: List
+ + +
attach(Observer) : void detach(Observer) : void notfiy() : void
+
ConcreteSubj ect
update() : void
ConcreteObserv er
-
subejctState: Object
-
observerState: Object
+ + +
attach(Observer) : void detach(Observer) : void notfiy() : void
+
update() : void
«property get» + getSubejctState() : Object «property set» + setSubejctState(Object) : void
Programação Orientada a Objetos 2
110
Flávio de Oliveira Silva, M.Sc.
Observer Exemplo
A medida que as ações de uma empresa (Stock) forem alteradas os investirores (Inverstor) serão notificados
class GOF-Observ er
Stock -
symbol: String price: double investors: List = new List
+ + + + + + +
Stock(String, double) attach(IInvestor) : void detach(IInvestor) : void notify() : void getPrice() : double setPrice(double) : void getSymbol() : String
«interface» IInvestor +
update(Stock) : void
-
name: String stock: Stock
+ + + +
Investor(String) update(Stock) : void getStock() : Stock setStock(Stock) : void
-stock
Petrobras
M i A li ti MainApplication
Inv estor +
Main() : void
+
Petrobras(String, double)
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
111
28
10/6/2011
Observer Exemplo - 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); petro setPrice(120 50); petro.setPrice(120.75); } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
112
Observer Exemplo - Código /// The 'Subject' abstract class public abstract class Stock { private String symbol; private double price; private List investors = new List(); 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){ investor.update(this); } System.out.println(""); }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
113
29
10/6/2011
Observer Exemplo - 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 2 Flávio de Oliveira Silva, M.Sc.
114
Observer Exemplo - 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 2 Flávio de Oliveira Silva, M.Sc.
115
30
10/6/2011
Observer Exemplo - 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() 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; } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
116
Command
Objetivo Motivação Uso Estrutura Exemplo Código
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
117
31
10/6/2011
Command Exemplo - Estrutura class GOF-Command -flipUpCommand
«interface» Command +
flipDownCommand
execute() : void
Sw itch PressSw itch +
main(String[]) : void
-
flipUpCommand: Command flipDownCommand: Command
+ + +
Switch(Command, Command) flipUp() : void flipDown() : void
FlipUpCommand -
theLight: Light
+ +
FlipUpCommand(Light) execute() : void
FlipDow nCommand -
theLight: Light
+ +
FlipDownCommand(Light) execute() : void
-theLight-theLight Light + + +
Light() turnOn() : void turnOff() : void
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
118
Command Có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(); } public void flipDown() { flipDownCommand.execute(); } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
119
32
10/6/2011
Command Có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 2 Flávio de Oliveira Silva, M.Sc.
120
Command Có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; } public void execute(){ theLight.turnOn(); } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
121
33
10/6/2011
Command Có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() { g (); theLight.turnOff(); } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
122
Command Código public class PressSwitch { // The test class or client public static void main(String[] args) { Light lamp = new Light(); Command switchUp p = new FlipUpCommand(lamp); 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 { System.out.println("Argument \"ON\" or \"OFF\" is required."); } } catch (Exception e) { System.out.println("Arguments required."); } } Programação Orientada a Objetos 2 } Flávio de Oliveira Silva, M.Sc.
123
34
10/6/2011
Command Có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() { flipUpCommand.execute(); } public void flipDown() { flipDownCommand.execute(); }
Programação Orientada a Objetos 2
}
Flávio de Oliveira Silva, M.Sc.
124
Strategy
Objetivo
Motivação ç
Definir uma família de algoritmos que podem ser intercambiáveis sendo possível alterar os algoritmos sem alterar o cliente que os utiliza 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 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
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
125
35
10/6/2011
Strategy Estrutura
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 (Client) Uma alteração no contexto pode O contexto é utlizado por um cliente (Client). indicar o uso de uma nova estratégia
class GOF-Strategy
«interface» Strategy
Context -
strategy: Strategy +
callAlgorithm() : void
Client
AConcreteStrategy +
BConcreteStrategy
callAlgorithm() : void
+
CConcreteStrategy
callAlgorithm() : void
+
callAlgorithm() : void
Programação Orientada a Objetos 2
126
Flávio de Oliveira Silva, M.Sc.
Strategy Exemplo
Neste caso a estratégia permite que o cliente (StrategyExample) utilize diferentes operações aritméticas conforme o contexto (Context) utilizado
class GOF GOF-Strategy Strategy Sample «interface»
Context strategy: Strategy
+ +
Context(Strategy) executeStrategy(int, int) : int
+
ConcreteStrategyAdd StrategyExample +
Strategy
-strategy
-
+
execute(int, int) : int
execute(int, int) : int
ConcreteStrategySubtract
ConcreteStrategyMultiply
+
+
execute(int, int) : int
execute(int, int) : int
main(String[]) : void
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
127
36
10/6/2011
Strategy Exemplo - Código interface 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; } } class ConcreteStrategyMultiply implements Strategy { public int execute(int a, int b) { System.out.println("Called ConcreteStrategyMultiply's execute()"); return a * b; } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
128
Strategy Exemplo - Código class Context { private Strategy strategy; // Constructor public Context(Strategy p ( gy strategy) 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()); 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); } Programação Orientada a Objetos 2 } Flávio de Oliveira Silva, M.Sc.
129
37
10/6/2011
Template
Objetivo
Motivação Uso
Define um modelo (template) de um algoritmo em deixando alguns passos para suas subclasses
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 Exemplo Código E l Códi
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
130
Template Estrutura
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) class GOF-Template
AbstractClass + + + +
templateMethod() : void baseOperation() : void primitiveOperation1() : void primitiveOperation2() : void
ConcreteClass1 + +
templateMethod(){ ... baseOperation(); ... primitiveOperation1(); ... primitiveOperation2(); }
ConcreteClass2
primitiveOperation1() : void primitiveOperation2() : void
+ +
primitiveOperation1() : void primitiveOperation2() : void
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
131
38
10/6/2011
Template Exemplo
Um jogo contém operações básicas que serão especializadas O template method aqui é playOneGame() class GOF GOF-Template Template
Game #
playersCount: int
+ + + + +
initializeGame() : void makePlay(int) : void endOfGame() : boolean printWinner() : void playOneGame(int) : void
Monopoly + + + +
Chess
initializeGame() : void makePlay(int) : void endOfGame() : boolean printWinner() : void
+ + + +
initializeGame() : void makePlay(int) : void endOfGame() : boolean printWinner() : void
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
132
Template Exemplo – 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()) { makePlay(j); j = (j + 1) % playersCount; } printWinner(); } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
133
39
10/6/2011
Template Exemplo – 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 // according to Monopoly rules } public void printWinner() { // Display who won } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
134
Template Exemplo – Código public class Chess extends Game { /* Implementation of necessary concrete methods */ public void initializeGame() { // Initialize players p 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 } public void printWinner() { // Display the winning player } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
135
40
10/6/2011
Template Exemplo – Código public class Monopoly extends Game { /* Implementation of necessary concrete methods */ public void initializeGame() { // Initialize players p 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 } public void printWinner() { // Display who won } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
136
Iterator
Objetivo
Fornece uma maneira de acessar os componentes de um objeto sem expor a sua representação interna
Motivação Uso Estrutura Exemplo Código
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
137
41
10/6/2011
Iterator Estrutura
O iterator (ListIterator) permite o acesso ao objeto da lista em que seja necessário conhecer o seu interior
Programação Orientada a Objetos 2
138
Flávio de Oliveira Silva, M.Sc.
Iterator Exemplo
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
ChannelIterator «interface» TV +
getIterator() : ChannelIterator
-
channels: List<String> currentPos: int = 0
+ + + +
ChannelIterator(List<String>) hasNext() : boolean next() : void currentItem() : String
+ + +
hasNext() : boolean next() : void currentItem() : String
-iterator
ConcreteTV -
iterator: ChannelIterator channels: List<String>
+ +
ConcreteTV() getIterator() : ChannelIterator
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
139
42
10/6/2011
Iterator Có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 2 Flávio de Oliveira Silva, M.Sc.
140
Iterator Código //Concrete Aggregator public class ConcreteTV implements TV{ private ChannelIterator iterator; private List<String> p g channels;; public ConcreteTV() { iterator = new ConcreteChannelIterator(channels); } public ChannelIterator getIterator() return iterator; }
{
}
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
141
43
10/6/2011
Iterator Có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; } public void next() { currentPos++; } public String currentItem() { return channels.get(currentPos); } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
142
Visitor
Objetivo
Motivação
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 de objetos e é executada sobre o mesmo p ç “visita” o conjunto j j 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
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
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
143
44
10/6/2011
Visitor Estrutura
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 2 Flávio de Oliveira Silva, M.Sc.
144
Visitor Estrutura
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
145
45
10/6/2011
Visitor Estrutura
Programação Orientada a Objetos 2
146
Flávio de Oliveira Silva, M.Sc.
Visitor Exemplo 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
+
calculatePostage() : double
PostageVisitor «interface» Visitable +
accept(Visitor) : void
«interface» -
totalPostageForCart: double
+ + + +
visit(Book) : void visit(CD) : void visit(DVD) : void getT otalPostage() : double
Visitor + + +
visit(Book) : void visit(CD) : void visit(DVD) : void
Element +
accept(Visitor) : void
Book -
price: double weight: double
+ +
getPrice() : double getWeight() : double
CD
DVD
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
147
46
10/6/2011
Visitor Exemplo - 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 public class CD extends Element{ } //concrete element public class DVD extends Element{ }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
148
Visitor Exemplo - 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() { return weight; } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
149
47
10/6/2011
Visitor Exemplo - Código public 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 2 Flávio de Oliveira Silva, M.Sc.
150
Visitor Exemplo - Código public 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){ cd){...}} public void visit(DVD dvd){...} //return the internal state public double getTotalPostage() { return totalPostageForCart; } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
151
48
10/6/2011
Visitor Exemplo - Código public class ShoppingCart { //normal shopping cart stuff private ArrayList 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 2 Flávio de Oliveira Silva, M.Sc.
152
Mediator
Objetivo
Motivação
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 que esta comunicação entre estes objetos ocorra de forma independende uma das outras 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
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 Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
153
49
10/6/2011
Mediator Estrutura
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 2
154
Flávio de Oliveira Silva, M.Sc.
Mediator Exemplo A comunicação entre as entidades (FixedEntity e MobileEntity) é realizada através do mediator (ApplicationMediator) associado a cada entidade
class GOF - Mediator
Entity
«interface» Mediator +
-mediator
ApplicationMediator
Client +
main(String[]) : void
-
mediator: Mediator
+ + + +
Entity(Mediator) send(String) : void getMediator() : Mediator receive(String) : void
send(String, Entity) : void
-
MobileEntity
entitys: ArrayList<Entity> +
+ + +
receive(String) : void
ApplicationMediator() pp () addEntity(Entity) : void send(String, Entity) : void
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
FixedEntity +
receive(String) : void
155
50
10/6/2011
Mediator Có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); } public Mediator getMediator(){ //get access to the mediator return mediator; } public abstract void receive(String message); }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
156
Mediator Código public class ApplicationMediator implements Mediator { private ArrayList<Entity> entitys; public ApplicationMediator(){ entitys y = new ArrayList<Entity>(); 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 //don'tt tell ourselves if(entity != originator){ entity.receive(message); } } } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
157
51
10/6/2011
Mediator Código public 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 2 Flávio de Oliveira Silva, M.Sc.
158
Mediator Có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 ); desktop send("Hello World"); mobile.send("Hello"); } }
Programação Orientada a Objetos 2 Flávio de Oliveira Silva, M.Sc.
159
52