Padrão de protótipo em Java
1. Introdução
Neste tutorial, vamos aprender sobre um dosCreational Design Patterns - o padrão Prototype. Primeiramente, vamos explicar esse padrão e, em seguida, prosseguir para implementá-lo em Java.
Também discutiremos algumas de suas vantagens e desvantagens.
2. Padrão de protótipo
O padrão de protótipo é geralmenteused when we don’t want to keep creating new instances of a class. This is quite helpful in places where the cost of creating an object is high. Nesses casos, queremos minimizar o uso de recursos como memória.
Vamos usar uma analogia para entender melhor esse padrão.
Em alguns jogos, queremos árvores ou edifícios em segundo plano. Podemos perceber que não temos que criar novas árvores ou edifícios e renderizá-los na tela cada vez que o personagem se move.
Então, criamos uma instância da árvore primeiro. Em seguida, podemos criar quantas árvores quisermos desta instância (protótipo) e atualizar suas posições. Também podemos optar por mudar a cor das árvores para um novo nível no jogo.
O padrão Prototype é bastante semelhante. Em vez de criar novos objetos,we just have to clone the prototypical instance.
3. Diagrama UML
No diagrama, vemos que o cliente está dizendo ao protótipo para se clonar e criar um objeto. Prototype é uma interface e declara um método para clonar a si mesmo. ConcretePrototype1eConcretePrototype2 implementam a operação para clonar a si próprios.
4. Implementação
Uma das maneiras de implementar esse padrão em Java é usando o métodoclone(). Para fazer isso, implementaríamos a interfaceCloneable.
Quando estamos tentando clonar, devemos decidir entre fazer uma cópia superficial ou profunda. Eventualmente, tudo se resume aos requisitos.
Por exemplo, se a classe contém apenasprimitiveeimmutable fields, podemos usar uma cópia superficial.
Se ele contém referências a campos mutáveis, devemos usar umdeep copy. Podemos fazer isso com copy constructors or serialization and deserialization.
Vamos pegar o exemplo que mencionamos anteriormente eimagine that creating new instances of Tree is expensive.
Agora, vamos prosseguir para ver como aplicar o padrão Prototype usando a interfaceCloneable:
public class Tree implements Cloneable {
// ...
@Override
public Tree clone() {
Tree tree = null;
try {
tree = (Tree) super.clone();
} catch (CloneNotSupportedException e) {
// ...
}
return tree;
}
// ...
}
5. Teste
Agora vamos testar:
public class TreePrototypesUnitTest {
@Test
public void givenATreePrototypeWhenClonedThenCreateA_Clone() {
// ...
Tree tree = new Tree(mass, height);
tree.setPosition(position);
Tree anotherTree = tree.clone();
anotherTree.setPosition(otherPosition);
assertEquals(position, tree.getPosition());
assertEquals(otherPosition, anotherTree.getPosition());
}
}
Vemos que a árvore foi clonada do protótipo e temos duas instâncias diferentes deTree. Acabamos de atualizar a posição no clone e retemos os outros valores.
6. Vantagens desvantagens
Esse padrão é apropriado quando a criação de objetos é cara. Além disso, é útil quando nosso novo objeto é apenas ligeiramente diferente do nosso existente. Fazer isso também pode ajudar a melhorar o desempenho do aplicativo.
O padrão de protótipo, assim como qualquer outro padrão de design, deve ser usado apenas quando for apropriado. Como estamos clonando os objetos, o processo pode se tornar complexo quando houver muitas classes, resultando em uma confusão. Além disso, é difícil clonar classes que possuem referências circulares.
7. Conclusão
Neste tutorial, aprendemos os principais conceitos do padrão Prototype e vimos como implementá-lo em Java. Também discutimos alguns de seus prós e contras.
Como de costume, o código-fonte deste artigo está disponívelover on Github.