.NET - Princípios de Programação e Padrões de Projetos - II
Na primeira parte do artigo eu apresentei alguns conceitos básicos sobre os princípios SOLID e sobre os padrões de projeto. |
Vamos agora partir para a parte prática e mostrar os conceitos e a implementação dos principais padrões de projeto usando a linguagem C#.
Vou iniciar com o padrão Factory.
1 - Padrão de Projeto Factory (Fábrica)
É um padrão Criacional
Definição: Define uma interface para criar um objeto, mas deixa as subclasses decidirem que classe instanciar (Gamma, pag. 104).
Obs: O método Factory permite que uma classe adie a instanciação para as subclasses.
Este padrão é usado para substituir um construtor de classe(s), permitindo que o tipo de objeto a ser instanciado seja determinado em tempo de execução, sendo usado para controlar uma instanciação de classe.
O uso deste padrão de projeto reduz o acoplamento entre classes, e oferece muito mais flexibilidade no futuro, se os requisitos de sua aplicação mudarem.
Um benefício do padrão de Factory é permitir ao cliente focar no seu papel na arquitetura, porque permite a separação da criação e instanciação de objetos a partir do cliente.
Existem inúmeras variações do padrão Factory, mas em geral sempre temos um modelo básico que envolve os mesmos atores principais, um cliente, uma fábrica, e um produto.
Com o padrão Factory temos assim uma maneira simples e limpa para instanciar um objeto desconhecido para nós no momento da implementação. A única coisa que precisamos conhecer é a interface do objeto com um conjunto de propriedades predefinidos e métodos que precisamos usar.
Implementação
Existem diversas maneiras de implementar o padrão Factory (Fábrica) a seguir temos um modelo básico de implementação que creio seja uma dos mais simples:
Com base neste modelo vamos criar um novo projeto usando o Visual C# 2010 Express Edition do tipo Console Application com nome PadraoFactorySimples;
Vamos criar uma classe abstrata chamada Cargo que representa o cargo do funcionário na empresa (esta classe representa o produto) e que define o método Nome();
Esta classe é uma classe abstrata e não pode ser instanciada servindo como classe base para a criação de classes concretas:
abstract class Cargo { public abstract string Nome { get; } } |
classe abstrata que representa o produto |
A seguir vamos criar três classes : Gerente, Analista e Programador que implementa a classe abstrata Cargo sobrescrevendo o método Nome da classe Cargo retornando o nome do cargo:
class Gerente : Cargo { public override string Nome { get{return "Gerente";} } } class Analista : Cargo { public override string Nome { get{return "Analista";} } } class Programador : Cargo { public override string Nome { get{return "Programador";} } } |
Classes concretas que representam os produtos concretos. |
Agora vamos criar a classe Factory que representa a fábrica e que será responsável pela criação das instâncias dos objetos das classes concretas criadas anteriormente:
static class Factory { /// <summary> /// Decide qual classe instanciar /// </summary> public static Cargo Get(int id) { switch (id) { case 0: return new Gerente(); case 1: case 2: return new Analista(); case 3: default: return new Programador(); } } } |
classe que representa a fábrica |
No método Main() da classe Program vamos utilizar a fabrica para criar as instâncias das classes concretas conforme o objeto desejado, no caso usamos um laço for/next para invocar o método Get() da classe factory passando o id do objeto desejado:
class Program { static void Main(string[] args) { Console.WriteLine("Implementação do padrão Factory "); Console.WriteLine("--------------------------------"); for (int i = 0; i <= 3; i++) { var cargo = Factory.Get(i); Console.WriteLine("Quando id = {0}, cargo = {1} ", i, cargo.Nome); } Console.ReadKey(); } } |
Esta implementação é bem simples mas apresenta o seguinte problema:
Uma variação desta implementação para contornar o problema acima é vista na figura abaixo onde podemos criar uma fábrica abstrata e a partir dela criar tantas classes concretas quanto forem necessárias:
Vamos implementar esta variação criando uma fábrica abstrata que defina o método CriaCargos() que irá gerar as instâncias dos objetos concretos:
abstract class Fabrica { private ArrayList cargos = new ArrayList(); // Construtor chama a Fábrica public Fabrica() { this.CriaCargos(); } public ArrayList Cargos { get { return cargos; } } // Fábrica public abstract void CriaCargos(); } |
A seguir vamos criar as fábricas concretas que implementam a fábrica abstrata e que serão responsáveis pela criação dos objetos. As fábricas concretas sobrescrevem o método CriarCargos() e retornam os objetos para o cliente:
class Administracao : Fabrica { // Implementação da Fábrica public override void CriaCargos() { Cargos.Add(new Gerente()); } } class Tecnologia : Fabrica { // Implementação da Fábrica public override void CriaCargos() { Cargos.Add(new Analista()); Cargos.Add(new Programador()); } } |
A utilização da fábrica abstrata é feita no método Main() da classe Program() que cria as instâncias das fábricas concretas e gera os objetos desejados:
static void Main(string[] args) { //Os construtores chamam a Fábrica Fabrica[] fabricantes = new Fabrica[2]; fabricantes[0] = new Administracao(); fabricantes[1] = new Tecnologia(); Console.WriteLine("Implementação padrão Abstract Factory "); Console.WriteLine("-----------------------------------------"); foreach (Fabrica fabricante in fabricantes) { Console.WriteLine("\n" + fabricante.GetType().Name + "--"); foreach (Cargo cargo in fabricante.Cargos) { Console.WriteLine(" " + cargo.GetType().Name); } } Console.ReadKey(); } |
Pegue o projeto completo aqui: PadraoFactorySimples.zip
Slm 131:1
Senhor, o meu coração não é soberbo, nem os meus olhos são altivos; não me ocupo de assuntos grandes e maravilhosos demais para mim.Slm 131:2
Pelo contrário, tenho feito acalmar e sossegar a minha alma; qual criança desmamada sobre o seio de sua mãe, qual criança desmamada está a minha alma para comigo.Slm 131:3
Espera, ó Israel, no Senhor, desde agora e para sempre.Em artigos futuros estarei implementando outros padrões de projetos na linguagem C#. Aguarde...
Padrões de Projeto - O modelo MVC - Model View ... - Macoratti.net
VB .NET - Usando Padrões de Projetos na prática - Macoratti.net
Os 7 Principios do desenvolvimento de software - Macoratti.net