• Nenhum resultado encontrado

PrototypeClone

N/A
N/A
Protected

Academic year: 2021

Share "PrototypeClone"

Copied!
5
0
0

Texto

(1)

Padrões de Projeto

Prototype

Fábio Gondim

fmgondim@terra.com.br

Intenção:

Especificar os tipos de objetos a serem criados usando uma instância protótipo e criar novos objetos pela cópia deste protótipo.

2

Considerações

:

• A intenção do padrão é a passagem de um objeto que será utilizado como um gabarito para a criação de um novo objeto que contenha as mesmas características do anterior.

3

• Não sendo os detalhes de implementação do objeto plenamente conhecidos não é possível criar uma nova instância da mesma classe concreta e copiar todos os seus dados. • Ainda que a interface do objeto seja

conhecida, alguns destes dados podem ser privados e não dispor de métodos de acesso.

4

• A idéia é, então, pedir ao próprio objeto, seguindo-se o princípio do especialista*, que forneça uma cópia de si mesmo (clone) quando for solicitado.

*Especialista na Informação ou Especialista

Atribuir uma responsabilidade ao especialista na informação: a classe que tem a informação necessária para satisfazer a responsabilidade.

5

Estrutura

(2)

Participantes:

Prototype: Declara uma interface para clonar a si mesmo.

ConcretePrototype: Implementa uma

operação para clonar a si mesmo.

Client: Cria um novo objeto solicitando a um protótipo que clone a si mesmo.

Colaborações:

• Um cliente solicita a um protótipo que clone a

si mesmo. 7

O padrão Prototype

na linguagem Java

8

A interface Cloneable

Java fornece uma interface simples, chamada Cloneable, que provê uma implementação do padrão Prototype. Se a classe que contiver o método clone não implementar a interface Cloneable será lançada uma exceção

CloneNotSupportedException. Por convenção, classes que implementam esta interface devem sobrescrever o método protegido, clone(), herdado da classe Object para torná-lo público conforme explicamos a seguir.

9

A classe Object define o método clone da seguinte forma:

protectedObjectclone() throws CloneNotSupportedException Visto que a implementação de clone(), definida em java.lang.object, é protegida (protected), é necessário sobrescrever o método clone para aumentar a sua

visibilidadepara publice poder realizar uma chamada a super.clone().

publicclass CopyMe implements Cloneable {

public Object clone() throws CloneNotSupportedException { return super.clone();

}

} 10

Uma outra alternativa é declarar o tipo de retorno como sendo da própria classe do objeto que está sendo clonado para que não seja necessário realizar a coerção de tipos (casting) na chamada ao método.

public classCopyMeimplements Cloneable {

publicCopyMeclone() throws CloneNotSupportedException { return(CopyMe)super.clone();

} }

11

• O método Object.clone ajuda você a escrever métodos clone para as suas próprias classes. • Um método clone retorna um novo objeto cujo

estado inicial é um cópia do estado atual do objeto sobre o qual clone foi invocado. • Alterações subseqüentes no novo objeto

clonado não devem afetar o estado do objeto original (ver exceções adiante).

(3)

Resumindo:

Object.cloneverifica se o objeto sobre o qual foi invocado implementa a interface Cloneablee

lança CloneNotSupportedExceptionse ele não o

faz. Caso contrário, Object.clonecria um novo objeto exatamente do mesmo tipo do objeto original sobre o qual clone foi invocado e inicializa os campos do novo objeto clonado para terem os mesmos valores dos campos do objeto original. Quando Object.clonetermina, ele retorna uma referência do novo objeto.

13

Qual a relação entre os atributos do objeto original e da sua cópia após a chamada a Object.clone?

Tipos primitivos (boolean, char, byte, short, int, long, float e double): é feita uma cópia do atributo com endereços de memória

diferentes, de forma que alterações

subseqüentes nos valores de um objeto não refletirão no outro (os atributos são

independentes).

14

Strings: como as Strings são imutáveisa alteração em um atributo deste tipo em um objeto clonado não refletirá em seu original. Veja a explicação nos slides seguintes.

15

Strings: Strings são objetos especiais que possuem particularidades em relação aos demais objetos. Uma dessas particularidades é que Strings são

imutáveis. Toda vez que uma String é criada , a JVM a coloca em uma parte especial da memória chamada String Pool. Quando já existe uma String com o mesmo valor a JVM não cria uma duplicata apenas faz referência a entrada já existente.

16

Quando é feita qualquer alteração no valor atribuído a uma String uma nova String é criada sem que a antiga seja eliminada da String Pool. E infelizmente o Garbage Colector (Coletor de Lixo) não atua nesta área. Estes valores ficam lá enquanto a aplicação estiver ativa podendo ser, eventualmente, reaproveitados quando houver uma atribuição de um valor já existente.

17

// Após a execução deste trecho de código // teremos 10 (dez) objetos do tipo String // na String Pool e não apenas a String // de valor “0123456789” !!!

String s = “0”;

for (int i = 1; i < 10; i++) { s = s + i;

}

// Para evitar isto utilize StringBuffer ou // ou preferencialmente StringBuilder (Java 5) 18

(4)

Wrappers (Boolean, Character, Byte, Short, Integer, Long, Float e Double): da mesma forma que as Strings, Wrappers são imutáveis e, portanto, a alteração em um atributo deste tipo em um objeto clonado não refletirá em seu original.

19

Objetos de tipos definidos no programa ou pela linguagem (Vector, Array, ArrayList, etc.)

excetuando-se os anteriormente descritos (Strings e Wrappers): os atributos destes tipos farão referência aos mesmos objetos, tanto na cópia como no original. Se por exemplo, um objeto clonado possuir uma referência para um Array, o seu clone irá se referir ao mesmo Array e, desta forma, qualquer alteração, em qualquer um dos dois objetos (original e cópia) estará sendo feita sobre a mesma coleção e refletirá nos dois

objetos. 20

Clonagem Superficial (Cópia por Referência) versus

Clonagem Profunda (Cópia por Replicação) A implantação default de clone providencia o que é conhecido como clonagem ou cópia superficial(Shallow Copy) – ele simplesmente realiza um cópia campo a campo. Uma clonagem profunda(Deep Copy)deve clonar cada objeto referido por um campo e cada entrada em uma coleção. Isto se aplica recursivamente, e assim a clonagem profunda de um objeto deve clonar todos os objetos alcançáveis por este objeto. Em geral, clone é sobrescrito para realizar uma clonagem profunda sempre que uma clonagem superficial não é apropriada (ex: a clonagem de um objeto do tipo Carro que contém quatro objetos do tipo Roda – o conjunto de rodas certamente não deve ser compartilhado pelo carro original e

seus clones). 21

Referências Circulares A parte mais difícil do padrão Prototype é a implementação correta da operação Clone. Ela é particularmente difícil quando a estrutura de objetos contêm referências circulares [GoF].

public class Pai { Filho filho // ... }

public class Filho { Pai pai // ... }

Pai referencia Filho

Filho referencia Pai

22

public class Ovelha implements Cloneable {

private String cor; private Double h; private Ovelha mae;

public Ovelha(String cor, double h) { this.cor = cor;

this.h = h; }

public String getCor() { return cor; }

public void setCor(String cor) { this.cor = cor;

}

// Continua ...

23

public Double getH() { return h; }

public void setH(Double h) { this.h = h;

}

public Ovelha getMae() { return mae; }

public void setMae(Ovelha mae) { this.mae = mae;

}

public Ovelha clone() throws CloneNotSupportedException {

return (Ovelha) super.clone();

}

(5)

public class ClonaOvelha {

public static void main(String[] args) {

Ovelha ovelhaMae = new Ovelha("preta", new Double(0.55)); Ovelha ovelha = new Ovelha("cinza", new Double(0.6)); ovelha.setMae(ovelhaMae);

try {

Ovelha dolly = ovelha.clone(); System.out.println(dolly.getCor()); System.out.println(dolly.getH()); System.out.println(dolly.getMae().getCor()); dolly.getMae().setCor("grisalha"); System.out.println(dolly.getMae().getCor()); System.out.println(ovelha.getMae().getCor()); dolly.setCor("amarela"); System.out.println(dolly.getCor()); System.out.println(ovelha.getCor()); dolly.setH(new Double(0.8));

System.out.println(dolly.getH()); System.out.println(ovelha.getH());

// Continua ... 25

} catch (CloneNotSupportedException e) {

System.err.println("Não foi possível clonar o objeto"); } // final do try/catch

} // final do main

} // final da classe Saída do Programa:

cinza 0.6 preta grisalha grisalha amarela cinza 0.8 0.6 26

Bibliografia

• ARNOLD, Ken, GOSLING, James, HOLMES, David. A Linguagem de Programação Java, 4ª. Ed. Bookman. 2007;

• BATES, Bert, SIERRA Kathy. Head First Java, 2ª. Ed. O’Reilly, 2005;

• LARMAN, Craig. Utilizando UML e Padrões, 2ª. Ed. Bookman, 2004;

• GAMMA, E., HELM, R., JOHNSON, R. e VLISSIDES, J. Padrões de Projeto –

Soluções reutilizáveis de software orientado a objetos. Bookman. 1995.

Referências

Documentos relacionados

A Tabela 3 apresenta os parâmetros de perda de cocção, volume específico, dureza, atividade de água (Aa) e escore total para o pão controle e para os pães adicionados de mucilagem

É perceptível, desta forma, o constante aumento do aprofundamento dos personagens: os “príncipes” têm agora não só nome e falas, mas personalidades bem desenvolvidas,

Contribuições/Originalidade: A identificação dos atributos que conferem qualidade ao projeto habitacional e das diretrizes de projeto que visam alcançá-los, são de fundamental

logia avançada, com grande competição no mercado, tal como os de telecomunicações, para privilegiar-se dos ganhos de eficiência das operadoras, mantendo-se, tanto quanto possível,

Almanya'da olduğu gibi, burada da bu terimin hiçbir ayrım gütmeden, modern eğilimleri simgeleyen tüm sanatçılar için geçerli olduğu anlaşılıyor.. SSCB'de ilk halk

Atenas e Esparta eram as cidades mais importantes da Grécia Antiga e que deixaram uma herança visível até os nossos dias. As demais alternativas não são corretas, pois Roma fica

espaços públicos, focalizando a formação teatral nos públicos mais a descoberto no bairro (15-20 anos), criando um grupo de teatro comunitário, em parceria com as escolas locais,

A concentração de arsenato no rio Campumpema é a menor encontrada entre os três pontos de coleta em todos os períodos, concordando assim com a expectativa inicial de que este