20/03/2006

Form e Factory method ?

Olá Pessoal !

Estou usando a técnica de Factory method para criar os forms usando o nome do form, mais estou com um problema.

Tenho um cadastro de produtos criado, depois crio apartir dele uma tela de consulta grupo, só que, quando tento fazer um TypeCast do Consulta grupo para o Cadastro de produtos, dar um erro de memoria, como se o cadastro de produtos não tivesse criado.

Alguém pode me dar uma ajudinha ?

Obrigada.


Renatacoimbra

Respostas

20/03/2006

Marco Salles

Renta , postei algo a este respeito aqui no site.. Talvez voce não tenha este material ou talvez o tenha.. Mas se quiser dar uma olhada , conten a unit e o do método , assim com um breve exemplo..

Se voce quiser dar uma olhada pode procura por Factory method , que vai achar


Responder Citar

20/03/2006

Renatacoimbra

Oi Marco Salles !

eu tenho o exemplo, da revista de Nro 69, estou usando ele, o problema é esse q citei no post acima.

usando esse método, quando tento fazer um typeCast tipo:

CadProdutos.Edit1.Text := CadGrupo.DataSetCAMPO.asString;

dar erro, como se o cadastro de produtos não tivesse criado.


[]´s


Responder Citar

21/03/2006

Marco Salles

Tenho um cadastro de produtos criado,


depois crio apartir dele uma tela de consulta grupo,


Como voce cria o Cadastro Tela de Consulta a partir do Form Cadastro de produtos ????

Voce continua usando o método ??? Ou cria usando application.crteateForm????


Responder Citar

21/03/2006

Michael

Ser ver seu código fica difícil dar um diagnóstico. De qualquer forma, de onde vc está acessando o cadastro de produtos? Se for de outro formulário que não ele próprio - o que parece ser, afinal não faria muito sentido o contrário - vc vai precisar declarar sua unit para ter acesso à classe do form. E nesse caso a utilidade da factory deixa de existir.

Essa é uma das desvantagens de se usar uma fábrica - pelo menos como a concepção padrão define o termo: cada artefato produzido por ela é independente um do outro, sequer sabem que eles existem. Isso poderia ser contornado se todos os objetos criados pela factory fossem do mesmo tipo, o que não é o caso de formulários Delphi.

[]´s


Responder Citar

21/03/2006

Renatacoimbra

OI Pessoal, bom dia !


Eu estou criando meu Cadastro de Produtos apartir do Projeto usando Factory, daí do cadastro de produtos estou criando um outro form que é uma consulta.

Tentei criar o form COnsulta das duas formas usando o método Factory ou usando o método tradicinal, das duas formas dar o erro.

Olha a classe:


TCriaForm = class
  private
    FList: TStrings;
  public
    constructor Create;
    destructor Destroy; override;
    function Nome(const aFormName: string): TFrm_Form;
    procedure RegisterForm(const aFormName: string; aFormClass: TComponentClass);
  end;

var
  _CriaForm: TCriaForm;

  function CriaForm: TCriaForm;

implementation

constructor TCriaForm.Create;
begin
  inherited Create;
  FList := TStringList.Create;
end;

function TCriaForm.Nome(const aFormName: string): TFrm_Form;
var
  i : integer ;
begin
  //result := nil;
  i := FList.IndexOf(aFormName);
  Assert(i <> -1, ´Formulário  ´+ aFormName +´ não existe´);
  Result := TComponentClass(FList.Objects[i&93;).Create(nil) as TFrm_Form;
end;

destructor TCriaForm.Destroy;
begin
  FList.Free;
  inherited;
end;

procedure TCriaForm.RegisterForm(const aFormName: string;
  aFormClass: TComponentClass);
var
  i: integer;
begin
  i := FList.IndexOf(aFormName);
  if i = -1 then
    FList.AddObject(aFormName, TObject(aFormClass));
end;

function CriaForm: TCriaForm;
begin
  result := _CriaForm;
end;

initialization
  _CriaForm := TCriaForm.Create;

finalization
  _CriaForm.Free;

end.





// Para Criar o Form Produtos FForm := CriaForm.Nome(´Frm_Produtos´); FForm.Show; [/code] Depois eu uso apartir do cadastro de produtos para criar uma consulta:

Frm_ConsultaGrupo :=  Frm_ConsultaGrupo.Create(nil);
Frm_ConsultaGrupo.ShowModal;

Depois preciso fazer: Frm_Produtos.Propriedade := Frm_ConsultaGrupo.Propriedade; aí que dar o erro, como se o frm_Produtos não fora criado



Responder Citar

21/03/2006

Marco Salles

O que voce tem que fazer é o seguinte

1) No[b:af80637888] form Principal declare FForm como Public [/b:af80637888]ou a deixe em private e crie um método para acessa-lo .. Mas vamos deiza-la em Public para não nos estender

2)No form Produtos na parte [b:af80637888]Implementation[/b:af80637888] declare

na seccçao [b:af80637888]Public[/b:af80637888] Um Variavel

public
    FFormB : TForm;
    { Public declarations }


implementation

uses 
FormFactoryU;


3)No form Frm_ConsultaGrupo na secção implementation declare

implementation
uses FormFactoryU,unitDoFormProduto,UnitDoFormPrincipal;


Não esqueça de fazer Tambem na unit do Form Consulta
initialization
  FormFactory.RegisterForm(´FormConsulat´, TFormConsulta);


Para criar o FormConsulta atraves do FormProduto

 FFormB := FormFactory.CreateForm(´FormConsulta´);
  FFormB.ShowModal;
  FreeAndNil(FFormB);


Agora com essas definiçoes , voce pode acessar as propriedades , fazendo o TypCast Correto

Por exemplo

TformProduto(FormPrincipal.FForm).Componente.Propriedade:=
TformConsulta(TformProduto(FormPrincipal.FForm).FFormB).Componete.Propriedade;


So que isto conforme foi mencionado , descaracteriza o factory Method

O Grande problema é que apos voce criar um form usando o Método , por exemplo o formProduto , se no formulario , voce incluir um Botão e testar

If assigned(FormProduto) Then

[b:af80637888]Voce vera que é Nil.. Por isso as mensagens de acesso Violado que voce deve estar recebendo[/b:af80637888]


Responder Citar

21/03/2006

Massuda

aí que dar o erro, como se o frm_Produtos não fora criado
Pelo seu código, a [b:394311d770]variável[/b:394311d770] frm_Produtos não é inicializada, pois sua classe factory retorna diretamente uma instância da classe que é identificada pela string ´Frm_Produtos´. Note que não existe relação entre a variável e a string, embora você esteja se referindo as duas coisas como se fosse uma única coisa.

O que você pode fazer é atribuir o valor retornado pelo factory à variável frm_produtos ou fazer a classe do form identificado por ´Frm_Produtos´ ser um singleton (se seu sistema permitir ter apenas um form desse tipo).


Responder Citar

21/03/2006

Marco Salles

aí que dar o erro, como se o frm_Produtos não fora criado Pelo seu código, a variável frm_Produtos não é inicializada, pois sua classe factory retorna diretamente uma instância da classe que é identificada pela string ´Frm_Produtos´. Note que não existe relação entre a variável e a string, embora você esteja se referindo as duas coisas como se fosse uma única coisa.


[b:342af0d8d1]isto que eu quis dizer , quando deu o exemplo do Assigned[/b:342af0d8d1]

O que você pode fazer é atribuir o valor retornado pelo factory à variável frm_produtos


é uma maneira mais limpa de fazer a conversão.. Pois afinal voce estara se referindo ao mesmo form apenas com outro Nome

:arrow: Na criação :do [b:342af0d8d1]form produto[/b:342af0d8d1].. Pode ser no[b:342af0d8d1] OnShow[/b:342af0d8d1]

 TForm(formProduto):=(FormPrincipal.FForm);


[b:342af0d8d1]a unica diferença ai é que voce nesse caso tem que incluir na secçao uses do FormProduto a Unit Do Form Principal... [/b:342af0d8d1]O Que não era necessário na conversão anterior que lhe passei..

:arrow: Na criação do [b:342af0d8d1]FormCadastro [/b:342af0d8d1], pode ser no[b:342af0d8d1] OnShow[/b:342af0d8d1]

Tform(FormCadastro):=FormProduto.FFormB;


Ai basta fazer em qualquer botão ou método

exemplo :

FormProduto.Edit1.text:=FormCadastro.Edit1.text;


[b:342af0d8d1]Obs) Renata estas atribuiçoes tem que vir no OnShow antes de qualquer método , senão pode aparecer erros de acesso Violado[/b:342af0d8d1]

ou fazer a classe do form identificado por ´Frm_Produtos´ ser um singleton (se seu sistema permitir ter apenas um form desse tipo).


Isto eu nun entendi :?: :?: :?:

Mas pode testar isto renata que dá


Responder Citar

21/03/2006

Massuda

[quote]ou fazer a classe do form identificado por ´Frm_Produtos´ ser um singleton (se seu sistema permitir ter apenas um form desse tipo).
Isto eu nun entendi?[/quote:c0b0a1a67b]Pensando bem, isso não tem muita relação com o problema. Por favor, desconsidere esse comentário.


Responder Citar

21/03/2006

Renatacoimbra

Obrigada Marco Salles e Massuda pelas dicas

Nos testes que fiz funcionou blz.

Mais eu resolvir a não usar esse método para criação dos Forms, eu uso módulos em Packages BPL, vai dar muitos problemas pra mim pelo jeito.


Obrigada.


Responder Citar