Padrão de Projeto Factory em Delphi


No exemplo retornar o tipo de uma pessoa que pode ser (Física, jurídica ou estrangeira).

Minha definição de Factory nesse exemplo seria passar a responsabilidade da criação do objeto TPessoa para outro objeto.
Essa unit é responsável pela classe base TPessoa na qual possui um método Nome no qual será implementado em outro momento.

unit UPessoas_Tipo;
interface

type
    TPessoa = class
    function Nome: string; virtual; abstract;
end;

implementation

end.


Essa unit PessoaCliente é responsável pela classe TPessoaCliente que herda da classe base TPessoa na qual implementará o método Nome, observe que ele irá mostrar o nome da classe e o nome da pessoa para facilitar o desenvolvimento.
unit UPessoaFisica;
interface

type
  TPessoaFisica = class(TPessoa)
  function Nome: string; override;
end;

implementation

function TPessoaFisica.Nome: string;
begin    
  Result := ClassName + ': Física';
end;

Essa unit PessoaJuridica é semelhante a da classe TPessoaFisica
unit UPessoaJuridica;
interface

type     
  TPessoaJuridica = class(TPessoa)
  function Nome: string; override;
end;

implementation

function TPessoaJuridica.Nome: string;
begin
  Result := ClassName + ': Jurídica';
end;


Essa unit PessoaEstrangeira é semelhante a da classe TPessoaFisica
unit UPessoaEstrangeira;
interface

type
  TPessoaEstrangeira = class(TPessoa)
  function Nome: string; override;
end;

implementation

function TPessoaEstrangeira.Nome: string;
begin
  Result := ClassName + ': Estrangeira';
end;

Essa unit PessoaFactory é responsável por criar e devolver a instanciar do objeto de acordo com o parâmetro informado TTipoPessoa.
Observe que o retorno é do tipo base TPessoa, facilitando a ampliação para outras classes como, por exemplo, TUsuario.
unit UPessoas_Factory;
interface

uses UPessoaJuridica, UPessoaEstrangeira, UPessoaFisica, Classes;

type
  TTipoPessoa = (tpFisica, tpJuridica, tpEstrangeira);
  TPessoas_Factory = class
public
  function CriarPessoa(const APessoa: TTipoPessoa): TPessoa;
end;

implementation

{ TPessoas_Factory }

function TPessoas_Factory.CriarPessoa(const APessoa: TTipoPessoa): TPessoa;
begin
  Result := nil;
  case APessoa of
  tpFisica : Result := TPessoaFisica.Create;
  tpJuridica : Result := TPessoaJuridica.Create;
  tpEstrangeira : Result := TPessoaEstrangeira.Create;
end;


A unit Principal só tem conhecimento da unit PessoaFactory, que cria e chama o método nome de acordo com o parâmetro informado.

procedure TForm1.DoCreate;
var 
  wPessoa : TPessoas_Factory;
begin
  inherited;
  wPessoa := TPessoas_Factory.Create;
  try
    Memo1.Clear;
    Memo1.Lines.Add(wPessoa.CriarPessoa(tpFisica).Nome);
    Memo1.Lines.Add(wPessoa.CriarPessoa(tpJuridica).Nome);
    Memo1.Lines.Add(wPessoa.CriarPessoa(tpEstrangeira).Nome);
  finally
    wPessoa.Free;
  end;
end;



Um comentário: