Padrão Criacional: Protótipo
Este artigo discute como novos objetos podem ser criados a partir de objetos existentes usando o padrão protótipo.

O que é isso?
O padrão Prototype é um padrão criacional no qual novos objetos são criados copiando um objeto existente. O objeto cujas cópias são feitas é chamado de protótipo . Para entender melhor os objetos, você pode considerar o objeto protótipo como a “semente” a partir da qual todos os outros objetos são criados. Portanto, você pode perguntar por que não criaria novos objetos quando necessário, em vez de clonar os existentes. As motivações para protótipos de objetos são as seguintes:
- Às vezes, criar um novo objeto é mais caro do que copiar um existente.
- Imagine se você não pudesse acessar o construtor de uma classe estaticamente e o ambiente de tempo de execução tivesse que criar uma instância de cada classe carregada dinamicamente. Em vez disso, o aplicativo poderia solicitar objetos de um gerenciador de protótipos que retornaria clones de protótipos.
- Você pode reduzir significativamente o número de classes em um sistema variando os valores de objetos clonados de uma instância prototípica.
Diagrama de classe
O diagrama de classes contém as seguintes entidades:
- Protótipo
- Protótipo de Concreto
- Cliente

Vamos pegar o exemplo de uma aeronave para entender melhor o padrão do protótipo. Primeiro, criamos uma classe para representar o F-16. Mas sabemos que o F-16 tem algumas variantes. Assim, para representar cada uma das variantes do F16, podemos criar subclasses. Mas então acabaremos com várias subclasses em nosso sistema. Além disso, vamos supor que as variantes do F16 diferem apenas por seus tipos de motor. Então, uma possibilidade seria manter uma única classe F16, mas adicionar um método para definir o tipo de motor da aeronave. Dessa forma, podemos criar um único objeto F16 como protótipo e cloná-lo para várias versões de aeronaves.
Primeiro, criamos uma interface.

A classe F-16 implementa sua interface assim:

O cliente pode usar o padrão assim:

Observe que o método clone da interface IAircraftPrototype retorna um tipo abstrato . Os clientes não sabem quais implementações diferentes da mesma interface criarão subclasses concretas. Por exemplo, a classe Boeing747 pode ser aprovada, produzindo cópias de qualquer protótipo aprovado (um F16 ou um Boeing747). O padrão de protótipo ajuda a eliminar subclasses, pois o comportamento de objetos de protótipo pode ser variado compondo-os com subpartes.
Cópia rasa x profunda
O padrão de protótipo requer que a classe ou interface de protótipo implemente um método clone() . A clonagem pode ser superficial ou profunda. Por exemplo, se nossa classe F-16 tiver um objeto membro do tipo F16Engine , em uma cópia superficial, o objeto clonado apontaria para o mesmo objeto F16Engine do protótipo. Mas em uma cópia profunda, o objeto clonado obteria sua cópia de seu objeto de mecanismo e quaisquer objetos aninhados dentro dele. Não haverá nenhum compartilhamento de nenhum campo — aninhado ou não — entre o protótipo e seu clone.
Carregamento Dinâmico
O padrão de protótipo pode facilitar o carregamento dinâmico de classes. O carregamento dinâmico permite que você carregue uma classe em tempo de execução em vez de ter a classe disponível em tempo de compilação. Em uma linguagem que suporta carregamento dinâmico, um framework irá criar uma instância da classe carregada e registrá-la em uma entidade gerenciadora. Então, em tempo de execução, seu aplicativo pode solicitar a esse gerenciador que forneça a você um objeto que pertence a essa classe.
Outros exemplos
Na linguagem de programação Java, a classe Object possui um método clone. A classe implementa a interface java.lang.Cloneable .
Ressalvas
A implementação do método clone pode ser difícil devido às referências circulares.