Desenvolvimento - C#

Prototype - Padrão de Projeto com Microsoft .NET C#

Veja neste artigo uma introdução sobre o padrão de projeto Prototype, entenda quando é recomendado o seu uso, e como implementá-lo ao seu projeto.

por Flávio Secchieri Mariotti



Veja neste artigo uma introdução sobre o padrão de projeto Prototype, entenda quando é recomendado o seu uso, e como implementá-lo ao seu projeto.

Introdução

Padrão de Projeto ou em inglês Design Patterns, é uma forma organizada de criar soluções para os problemas recorrentes do dia a dia de um programador.

Porque devo usar Padrão de Projeto

É possível desenvolver software sem utilizar padrões de projetos, e o fato de usar não característica um código ou software de qualidade. Padrão de projeto é somente um dos vários detalhes que compõem um o desenvolvimento de um software. Usar padrão de projeto é uma escolha que cabe a cada desenvolvedor/time. Existem casos onde as empresas desenvolvem seus próprios padrões de projetos e suas framework de trabalho.

O conceito de padrão de projeto foi criado na década de 70 pelo arquiteto e matemático Christopher Alexander um australiano que foi um dos principais críticos da arquitetura moderna. Alexander definiu dois pontos fundamentais para criação de um padrão, apontando as características e formato básico que um "objeto" deve ter para ser classificado como padrão.

Características

· Encapsulamento

· Generalidade

· Equilíbrio

· Abstração

· Abertura

· Combinatoriedade

Formato

· Nome

· Exemplo

· Contexto

· Problema

· Solução

Agora podemos entender o que existe em comum no trabalho de Alexander com o desenvolvimento de software, podemos compreender o que é necessário para criação de um padrão. Vamos então entender quais os benefícios e vantagens que ao desenvolver software utilizando padrões de projetos o desenvolvedor/time pode obter.

 Alguns acontecimentos são comuns no dia a dia das fabricas de software, tais como: giro de funcionários; mudanças no sistema em produção; correção de erros; implementação de novos recursos; customizações especificas e etc. Os padrões de projetos tem como objetivo facilitar o desenvolvimento de software com a reutilização de soluções já implementadas. Atenção! Não estamos falando de reutilização de código e sim em um desenvolvimento padronizado com: vocabulário unificado; facilidade para comunicação e leitura do código; documentação padronizada; compreensão rápida do código para novos e antigos integrantes do time de TI.

Prototype - Padrão de Projeto

Uma definição simples e objetivo do padrão de projeto Prototype pode ser encontrada no Wikipédia. Segundo o portal, "Prototype, na ciência da computação, é um padrão de projeto de software que permite a criação de objetos a partir de um modelo original, ou protótipo."

Sendo assim, este padrão permite clonar/copiar um objetivo a partir de uma classe, ou seja, o desenvolver pode criar uma instância clonada e definir o objetivo em tempo de execução.

Classificação

Padrões de projetos descreve 23 modelos de desenho, porem cabe ressaltar que existem centenas de padrões. No famoso livro Design Patterns dos autores Gamma, Helm, Johnson e Vlissides é apresentado 23 padrões de projeto, documentados e já conhecidos no mundo do desenvolvimento de software. É importante lembrar que isso não significa que esses padrões são os mais úteis para se implementar, sendo assim, vale a pena pesquisar padrões em outras fontes.

Estes 23 padrões são divididos em padrões de criação, padrões estruturais e padrões comportamentais. Vamos explorar os 23 padrões de projeto na serie de artigo sobre o assunto. O padrão de projeto Prototype está classificado como padrões de criação.

Quando devo usar o padrão de projeto Prototype?

Para entendermos melhor onde é recomendável o uso do padrão de projeto Prototype, vamos imaginar um cenário com o padrão de projeto Abstract Factory. Suponhamos que seu aplicativo oferece ao seu cliente um recurso que disponibiliza diversas interfaces de usuário com diferentes contextos. Agora para deixar o cenário próximo do real, suponhamos que o cliente necessite de vários recursos com diferentes interfaces de usuário no mesmo contexto. Observe na figura 1 uma demonstração gráfica do cenário.  

Figure 1. Demonstração gráfica de dois objetos abstract factory com diferentes interfaces de usuário.

Vamos imaginar que o diagrama contém um numero grande de InterfaceUsuario0-1000 e um numero grande de métodos na classe principal. Com isso, podemos perceber que este projeto contém um objeto (InterfaceUsuario) que tem um conjunto completo de variáveis de instância prototípica, são elas: Recurso1 (Componete1), Recurso2 (Componete2), Recurso3 (Componete3) e assim por diante.

Claro que podemos criar os métodos estáticos na classes e fazer com que este método possam instanciar a classe principal com os valores que são apropriados para uma exibição e retornar o objeto para uso como conjunto GUI. Porem vamos imaginar um contexto onde podemos fazer uso do recurso de protótipos, sendo assim, estamos sugerindo que: cada instância da interface do usuário se torne uma fábrica de interface de usuário, trabalhando como uma distribuição de copias a partir do protótipo.

O que significa Clonar um Protótipo?

A principal intenção do padrão de projeto Prototype é disponibilizar novos objetos a partir de um protótipo, ou seja, clonando um objeto existente. Sendo assim, o novo objeto terá as mesmas características (atributos e comportamentos) que o objeto pai. 

Implementando padrão de projeto Prototype

Vamos agora colocar em prática a teoria exposta acima. Para isso vamos criar um projeto e implementar o padrão Prototype e analisar seus recursos e comportamento.

Projeto classificação de produtos

Vamos desenvolver um projeto simulando uma lista de produtos. Suponhamos que a empresa "XVendeTudo" tem uma lista com milhares de produtos, dentre esses produtos, existem itens com a categoria especial. Esses produtos especiais necessitam de atributos específicos e dinâmicos.

A figura 2 representa graficamente as classes e interfaces que simulam o projeto.

Figure 2. Diagrama do projeto lista de produtos com padrão Prototype

Para implementação desde projeto vamos fazer uso de alguns recursos da framework .NET, dentre elas a interface ICloneable e o método MemberwiseClone().

Entendendo alguns recursos utilizados no exemplo

Interface ICloneable: Essa interface oferece suporte para clonagem de objetos, permitindo a criação de uma nova instância de uma classe com os mesmos valores da instância existente.

Method MemberwiseClone(): Esse método permite a criação de uma cópia superficial de um objeto.

Localização:

      Namespace: System

      Assembly: mscorlib (mscorlib.dll)

Código do projeto

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace PrototypeProject

{

    public class IdCaracteristicas

    {

        public int _IdFabricante;

        public int _IdPreco;

        public string _IdDescricao;

        public IdCaracteristicas(int vIdFabricante, int vIdPreco, string vIdDescricao)

        {

            this._IdFabricante = vIdFabricante;

            this._IdPreco = vIdPreco;

            this._IdDescricao = vIdDescricao;

        }

    }

    public class Produto : ICloneable

    {

        public int _IdCategoria;

        public string _Classificacao;

        public IdCaracteristicas IdCaracteristica;

        #region Metodos de clonagem

        public Object Clone()

        {

            return (Produto)this.MemberwiseClone();

        }

        public Object Copiar()

        {

            Produto copiaProduto = (Produto)this.MemberwiseClone();

           

            copiaProduto.IdCaracteristica = new                                    IdCaracteristicas(this.IdCaracteristica._IdFabricante,

                this.IdCaracteristica._IdPreco, this.IdCaracteristica._IdDescricao);

            return copiaProduto;

        }

       

        #endregion

    }

   

   

    class Program

    {

        public static void Main()

        {

            // Criando a primeira instância como Produto1

            Produto _Produto1 = new Produto();

            _Produto1._IdCategoria = 01;

            _Produto1._Classificacao = "Jogos";

            _Produto1.IdCaracteristica = new IdCaracteristicas(001, 01, "Este jogo contém todos os recursos novos");

            // Listando informações do Objeto instânciado

            ListarInfor(_Produto1);

            // Criando a segunda instância e efetuar o Clone do objeto Produto1

            Produto _Produto2 = (Produto)_Produto1.Clone();

            // Listando informações do Objeto clonado

            ListarInfor(_Produto2);

           

         

            // Customizando valores nas propriedades do Produto1 e listando

            // os valores do Produto1 e Produto2

            _Produto1._IdCategoria = 02;

            _Produto1._Classificacao = "Poker";

            _Produto1.IdCaracteristica = new IdCaracteristicas(001, 01, "Contém todas as técnicas do poker");

            // Analisando o resultado depois da customização...

            Console.WriteLine("   Valores das propriedades do Produto1: ");

            ListarInfor(_Produto1);

           

            Console.WriteLine("   Valores das propriedades do Produto2:");

            ListarInfor(_Produto2);

            // Criando uma instância com o método copiar que efetuar o clone e

            // instância um nova classe caractetisticas para o Objeto

            Produto _ProdutoEspecial = (Produto)_Produto1.Copiar();

           

            // Alterando o valor do objeto Produto1 e analisando o comportamento...

            _Produto1._IdCategoria = 05;

            _Produto1._Classificacao = "Tecnologia";

            _Produto1.IdCaracteristica = new IdCaracteristicas(001, 01, "Novos recursos do .NET");

           

            // Analisando o resultado depois da alteração...

            Console.WriteLine("   Valores das propriedades do Produto1: ");

            ListarInfor(_Produto1);

            Console.WriteLine("   Valores das propriedades do ProdutoEspecial:");

            ListarInfor(_ProdutoEspecial);

        }

        public static void ListarInfor(Produto vProduto)

        {

            Console.WriteLine("");

            Console.WriteLine("Categoria: {0}", vProduto._IdCategoria);

            Console.WriteLine("Classificação: {0}", vProduto._Classificacao);

            Console.WriteLine("Caracteristicas: {0}, {1}, {2}", vProduto.IdCaracteristica._IdFabricante,

                vProduto.IdCaracteristica._IdPreco, vProduto.IdCaracteristica._IdDescricao);

        }

    }

}

Conclusão

Pode-se concluir que o padrão de projeto Prototype permite a criação de novos objetos com base em um protótipo. Ao usar o padrão Prototype em vez de copiar o objeto pelo construtor, estamos evitando a cópia do estado original do objeto origem. Esse recurso pode ser considerável como uma vantagem para o desenvolvedor, sendo que o mesmo pode utilizar essa função em circunstâncias onde diferentes classes de objetos diferem apenas em seus atributos e não em seus comportamentos.

Podemos ressaltar também que, ao usar o padrão Prototype o desenvolvedor consegue criar novas classes em tempo de execução.

Comunicado Importante

Espero que tenham gostado do conteúdo explorado neste artigo, caso exista interesse em conhecer um pouco mais sobre padrão de projeto prototype. Informe seu interesse usando o recurso de "comentários" neste artigo ou qualquer dúvida relacionada ao conteúdo do mesmo.

Referência

Steven John Metsker. Design Patterns in C#, Addison-Wesley Professional, 2004.

Erich Gramma; Richard Helm; Ralph Johnson; John Vlissides. Design Patterns Elements

of Reusable Object-Oriented Software, Addison-Wesley Professional, 1994.

Flávio Secchieri Mariotti

Flávio Secchieri Mariotti - Especialista em Engenharia e Arquitetura de Software. Pós Graduado pelo Instituto de Pesquisa Avançada de Tecnologia IBTA em Engenharia de Software baseado em SOA. Bacharel em Sistemas de Informação pela UNIUBE e técnico em Processamento de Dados pela FEB. Consultor independente no desenvolvimento de software em arquitetura OO, SOA, GIS e Plataforma .NET.