C#
- Apresentando o padrão Prototype
![]() |
Neste artigo vou apresentar com o padrão criacional Gof Prototype. |
Segundo a
definição do livro da Gang of four (Gof) o objetivo do padrão
Prototype é : "Especificar tipos de objetos a serem
criados usando uma instância protótipo e criar novos objetos pela cópia desse
protótipo.”
Assim este padrão
permite a criação de novos objetos a partir de modelo original que é clonado sem
fazer o código ficar dependente de sua classe.
O padrão atua delegando o processo de clonagem para o próprio objeto que esta
sendo clonado, e, para fazer isso ele
declara uma interface comum para todos os objetos que suportam a clonagem e
permite clonar um objeto sem acoplar seu código à classe daquele objeto.
(Geralmente, a interface contém apenas um único método clonar.)
O conceito usado pelo padrão é copiar um objeto existente em vez de criar uma
nova instância do zero, algo que pode incluir operações custosa em termos de
memória e tempo. O objeto existente atua como um protótipo e contém o estado do
objeto. O objeto recém-copiado pode alterar as mesmas propriedades apenas se
necessário.
Essa abordagem economiza recursos e tempo dispendiosos, especialmente quando a
criação do objeto for um processo pesado.
Diagrama UML
No diagrama UML deste padrão temos os seguintes participantes:
1 - Prototype -
Declara uma interface para objetos capazes de clonar a si mesmo;
2 - ConcretePrototype
– Faz a implementação de um
Prototype (implementa uma operação para se
clonar)
3- Client –
Cria um novo objeto através de um Prototype que é
capaz de clonar a si mesmo;
Quando podemos usar o padrão Singleton
Podemos considerar o uso deste padrão :
a- Quando a
criação de novos objetos tem um grande custo e leva muito tempo;
b- Quando desejamos evitar criar um novo objeto utilizando a palavra new, o que
diminui o custo de memória;
c- Quando existir a necessidade de clonar (criar cópias exatas) um objeto.
d- Quando o sistema deve ser independente de como os seus objetos são criados e
:
- As classes a serem instanciadas forem definidas em tempo de
execução
- For mais conveniente copiar uma instância existente do que criar
uma
- Forem necessários objetos semelhantes aos objetos existentes
Vantagens e
desvantagens ao usar o padrão
Como vantagens do uso do padrão Prototype podemos citar :
E como desvantagem temos que :
Implementar o
padrão em uma hierarquia de classes já existente pode ser difícil, pois eles
devem implementar o método clone(), e alguns objetos podem estar usando objetos
internos que não suportam cópia ou podem ter referência circular
O uso excessivo do padrão pode afetar o desempenho, já que o próprio objeto de
protótipo precisaria ser instanciado se você usar um registro de protótipos
Processo de clonagem
O processo de clonagem de um objeto pode ser feito usando duas abordagens:
Usando a linguagem
C# podemos usar recursos que a própria linguagem oferece para facilitar a
implementação da clonagem, como o método Clone da interface
ICloneable que cria um novo objeto que é uma
copia da instancia atual, e
o método MemberwiseClone() que cria uma copia
superficial do objeto atual.
ICloneable.Clone() : Cria um novo objeto que é uma cópia da instância atual;
Object.MemberwiseClone() : Cria uma cópia superficial do Objeto atual;
Um cenário muito
comum de uso deste padrão e a clonagem de personagens em jogos onde geralmente é
necessário usar muitos objetos com as mesmas características básicas havendo a
repetição de muitos personagens com pequenas variações
Neste cenário criar cada objeto usando o operador new seria muito custoso em
termos de recursos usando a clonagem e o padrão Prototype
basta criar um objeto e fazer a clonagem alterando apenas algumas
características de alguns personagens.
Exemplo de aplicação do padrão
Prototype
Vejamos um exemplo de aplicação do padrão Prototype
onde vamos clonar um soldado e gerar um exercito de soldados.
Para isso vamos criar um projeto Console do tipo .NET 5.0 usando a linguagem C#.
Inicialmente vamos usar a abordagem Shallow Copy e
fazer uma clonagem superficial. Para isso vamos usar a interface
ICloneable da linguagem C# que define o contrato
para implementar o método clone que esta fazendo o papel do
Prototype.
Vamos criar uma classe Soldado que representa o
ConcretePrototype e vamos definir as propriedades
Nome , Arma e Acessorio; aqui também estamos
implementando o método Clone da interface que vai
permitir fazer a clonagem do objeto.
public class Acessorio { public string Nome { get; set; }
public object Clone() |
Vamos criar também
a classe Acessorio que representa um tipo
Acessorio que é uma classe com a propriedade Nome
que vai definir acessórios especiais de um soldado como visão noturna e recursos
especiais Temos aqui um tipo complexo e veremos como ele se comporta na
abordagem Shallow Copy.
Na classe Program que representa o
Client vamos criar o objeto
Soldado atribuir valores as suas propriedades e fazer a clonagem deste
objeto.
using Prototype1_ShallowCopy.ConcretePrototype; using static System.Console;
namespace Prototype1_ShallowCopy //clone1 do objeto original //clone2 do objeto original //exibe valores do objeto original //clone1 //clone2 ReadLine(); } |
Para isso vamos implementar a classe Soldado da seguinte forma, e esta classe vai implementar a interface ICloneable disponível na linguagem C#.
Vamos definir as
propriedades e vamos implementar o método Clone da
interface onde estamos retornando uma nova instância de
Soldado, e, no construtor recebemos a instancia e copiamos os valores das
propriedades.
Note que temos um construtor vazio para poder criar um objeto
Soldado inicial e fazemos a clonagem usando o
método Clone.
Aqui estamos usando a abordagem Shallow Copy pois
como você vai perceber apenas os tipos de valor ou tipos de referencia serão
copiados o tipo Acessorio por ser um tipo complexo
terá copiada somente a referencia para o tipo e não o valor.
Executando o projeto teremos o resultado abaixo:
Na próxima parte do artigo veremos como realizar uma cópia profunda ou
Deep Copy usando padrão
Prototype.
Pegue o código
do projeto aqui :
Prototype1.zip
"Os meus olhos anteciparam as vigílias da noite, para
meditar na tua palavra."
Salmos 119:148
Referências:
NET - Unit of Work - Padrão Unidade de ...
NET - O padrão de projeto Decorator
NET - Padrão de Projeto Builder
C# - O Padrão Strategy (revisitado)
NET - O padrão de projeto Command
NET - Apresentando o padrão Repository