Este é um post disponível para assinantes MVPEste post também está disponível para assinantes da ClubeDelphi DIGITAL
ou para quem possui Créditos DevMedia. Clique aqui para saber mais!
ou para quem possui Créditos DevMedia. Clique aqui para saber mais!
Design Patterns – Artigo Clube Delphi 123 - Parte 2
Neste artigo continuaremos o estudo sobre os padrões de projeto. Iremos abordar o padrão Abstract Factory, implementando-o de duas formas: como uma classe abstrata e como uma interface. Daremos um enfoque maior à segunda opção.
ClubeDelphi 123
[Artigo disponível no Leitor Digital DevMedia. Clique aqui para acessá-lo]
> Clique aqui para ler todos os artigos da ClubeDelphi 123
[Artigo disponível no Leitor Digital DevMedia. Clique aqui para acessá-lo]
> Clique aqui para ler todos os artigos da ClubeDelphi 123
Design Patterns – Parte 2
igo anterior fizemos uma introdução ao padrão de projeto Factory Method. Factory Method é um método que se responsabiliza pela criação (e possível configuração ou ligação) de um objeto ou de um grupo de objetos.
Nesse contexto o construtor de uma classe (Create no Delphi Win32, new NomeClasse no Delphi Prism) pode ser considerado como um método fábrica degenerado, pois cria apenas um tipo de objeto, sem parametrizá-lo muito e ainda tem um alto acoplamento com a unidade desta classe por motivos óbvios: ele foi escrito como método desta classe, nesta mesma unidade.
Neste artigo começaremos a falar sobre Abstract Factory. Imagine que você já tenha criado melhorias no seu sistema por delegar a criação de certos objetos a alguns métodos que serão usados por “clientes” (outros objetos que necessitem destes).
A limitação a que chegamos é que precisamos conhecer e instanciar uma classe fábrica concreta para cada tipo ou família de objetos que venhamos a criar. Se você criasse uma fábrica, por exemplo, de conexões com o Interbase, ela criaria tanto o IBConnection como os IBDataSets que você pedisse, e talvez uma outra fábrica concreta criasse AdoConnections e AdoDataSets para você.
O objetivo do Abstract Factory é criar uma interface comum para acesso e manipulação de qualquer fábrica concreta. Com o Abstract Factory você cria variáveis genéricas, com métodos que criarão o objeto que você precisa indiretamente, delegando aos descendentes da Abstract Factory a responsabilidade de saber qual o tipo de objeto correto a se criar.
Como sabemos, há duas formas de atribuir uma interface comum a todas as fábricas de objetos: ou elas são descendentes do mesmo ancestral comum ou elas implementam uma mesma interface.
Usaremos a segunda opção pelas vantagens que o uso de interfaces nos proporciona: contagem de referências e a possibilidade de criar uma fábrica concreta que não seja necessariamente “da família” das outras fábricas. Porém, antes de criar uma interface padrão para nossas fábricas concretas, vamos criar uma interface padrão para os produtos concretos. Isso flexibilizará nossa aplicação a tal ponto que para um objeto ser considerado um produto concreto basta que implemente a interface, mesmo que não seja “parente” dos outros produtos.
Chegaremos assim a um cenário em que virtualmente qualquer classe pode ser uma fábrica e criar qualquer tipo de produto.
Pense na paleta de componentes do Delphi. Se você já criou um componente sabe que componentes são apenas classes normais que descendem da classe TComponent, implementando certas funcionalidades para que o IDE do Delphi possa conhecê-las, interagir com elas e executar seu código em design time. Isso quer dizer que objetos da classe TEdit são criados quando você coloca um Edit em um formulário, e são destruídos quando você pressiona “delete”. Em Design Time os construtores e destrutores dos objetos são executados, portanto se existir um “ShowMessage(‘olá mundo’);” em um construtor de um componente ele será executado quando você colocar o componente no Form.
Então isso faz do IDE do Delphi, principalmente da paleta de componentes, uma gigantesca fábrica, que cria os componentes através de seus nomes de classe. Também aprenderemos como criar um objeto de uma classe a partir de seu nome.
Usando métodos fábrica com interfaces
No artigo anterior chegamos a criar uma classe para produto abstrato chamada TAbstractProduct, da qual descendiam TPessoaFisica e TPessoaJuridica, e criamos um outro tipo de Abstract Product que eram os formulários de cadastro: criamos um formulário “abstrato” para ser ancestral dos dois formulários (concretos) programados para interagir com os outros objetos concretos. Porém não tínhamos uma fábrica abstrata: a fábrica que fizemos era concreta.
O produto abstrato a que chegamos no artigo anterior poderia ser implementado como o da Listagem 1, com os métodos e propriedades comuns a todos os produtos, mas, em vez disso, vamos extrair de nossos produtos concretos uma interface em comum. Isso quer dizer que os produtos concretos não mais precisarão descender de um mesmo ancestral, bastando que implementem a mesma interface.
Listagem 1. O produto abastrato poderia ser uma classe assim
TAbstractProduct = class
public
function ShowWhoIAm: string; virtual; abstract;
function GetNome: string; virtual; abstract;
function GetDocumento: string; virtual; abstract;
procedure SetNome(valor:string); virtual; abstract;
procedure SetDocumento(valor:string); virtual; abstract;
property Nome: string read GetNome write SetNome;
property Documento: string read GetDocumento write SetDocumento;
"
Este é um post disponível para assinantes MVP
igo anterior fizemos uma introdução ao padrão de projeto Factory Method. Factory Method é um método que se responsabiliza pela criação (e possível configuração ou ligação) de um objeto ou de um grupo de objetos.
Nesse contexto o construtor de uma classe (Create no Delphi Win32, new NomeClasse no Delphi Prism) pode ser considerado como um método fábrica degenerado, pois cria apenas um tipo de objeto, sem parametrizá-lo muito e ainda tem um alto acoplamento com a unidade desta classe por motivos óbvios: ele foi escrito como método desta classe, nesta mesma unidade.
Neste artigo começaremos a falar sobre Abstract Factory. Imagine que você já tenha criado melhorias no seu sistema por delegar a criação de certos objetos a alguns métodos que serão usados por “clientes” (outros objetos que necessitem destes).
A limitação a que chegamos é que precisamos conhecer e instanciar uma classe fábrica concreta para cada tipo ou família de objetos que venhamos a criar. Se você criasse uma fábrica, por exemplo, de conexões com o Interbase, ela criaria tanto o IBConnection como os IBDataSets que você pedisse, e talvez uma outra fábrica concreta criasse AdoConnections e AdoDataSets para você.
O objetivo do Abstract Factory é criar uma interface comum para acesso e manipulação de qualquer fábrica concreta. Com o Abstract Factory você cria variáveis genéricas, com métodos que criarão o objeto que você precisa indiretamente, delegando aos descendentes da Abstract Factory a responsabilidade de saber qual o tipo de objeto correto a se criar.
Como sabemos, há duas formas de atribuir uma interface comum a todas as fábricas de objetos: ou elas são descendentes do mesmo ancestral comum ou elas implementam uma mesma interface.
Usaremos a segunda opção pelas vantagens que o uso de interfaces nos proporciona: contagem de referências e a possibilidade de criar uma fábrica concreta que não seja necessariamente “da família” das outras fábricas. Porém, antes de criar uma interface padrão para nossas fábricas concretas, vamos criar uma interface padrão para os produtos concretos. Isso flexibilizará nossa aplicação a tal ponto que para um objeto ser considerado um produto concreto basta que implemente a interface, mesmo que não seja “parente” dos outros produtos.
Chegaremos assim a um cenário em que virtualmente qualquer classe pode ser uma fábrica e criar qualquer tipo de produto.
Pense na paleta de componentes do Delphi. Se você já criou um componente sabe que componentes são apenas classes normais que descendem da classe TComponent, implementando certas funcionalidades para que o IDE do Delphi possa conhecê-las, interagir com elas e executar seu código em design time. Isso quer dizer que objetos da classe TEdit são criados quando você coloca um Edit em um formulário, e são destruídos quando você pressiona “delete”. Em Design Time os construtores e destrutores dos objetos são executados, portanto se existir um “ShowMessage(‘olá mundo’);” em um construtor de um componente ele será executado quando você colocar o componente no Form.
Então isso faz do IDE do Delphi, principalmente da paleta de componentes, uma gigantesca fábrica, que cria os componentes através de seus nomes de classe. Também aprenderemos como criar um objeto de uma classe a partir de seu nome.
Usando métodos fábrica com interfaces
No artigo anterior chegamos a criar uma classe para produto abstrato chamada TAbstractProduct, da qual descendiam TPessoaFisica e TPessoaJuridica, e criamos um outro tipo de Abstract Product que eram os formulários de cadastro: criamos um formulário “abstrato” para ser ancestral dos dois formulários (concretos) programados para interagir com os outros objetos concretos. Porém não tínhamos uma fábrica abstrata: a fábrica que fizemos era concreta.
O produto abstrato a que chegamos no artigo anterior poderia ser implementado como o da Listagem 1, com os métodos e propriedades comuns a todos os produtos, mas, em vez disso, vamos extrair de nossos produtos concretos uma interface em comum. Isso quer dizer que os produtos concretos não mais precisarão descender de um mesmo ancestral, bastando que implementem a mesma interface.
Listagem 1. O produto abastrato poderia ser uma classe assim
TAbstractProduct = class
public
function ShowWhoIAm: string; virtual; abstract;
function GetNome: string; virtual; abstract;
function GetDocumento: string; virtual; abstract;
procedure SetNome(valor:string); virtual; abstract;
procedure SetDocumento(valor:string); virtual; abstract;
property Nome: string read GetNome write SetNome;
property Documento: string read GetDocumento write SetDocumento;
"
A exibição deste artigo foi interrompida.
Este é um post disponível para assinantes MVPEste post também está disponível para assinantes da ClubeDelphi DIGITAL
ou para quem possui Créditos DevMedia. Clique aqui para saber mais!
ou para quem possui Créditos DevMedia. Clique aqui para saber mais!
Vitor Luiz Rubio
Analista de Sistemas Sr. na Editora Revista dos Tribunais. Trabalha com Delphi desde a versão 3. Formado em Processamento de Dados pela FATEC-SP
O que você achou deste post?
Cursos relacionados
Publicidade



