Array
(
)

Form e Factory method ?

Renatacoimbra
   - 20 mar 2006

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.


Marco Salles
   - 20 mar 2006

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


Renatacoimbra
   - 20 mar 2006

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


Marco Salles
   - 21 mar 2006


Citação:
Tenho um cadastro de produtos criado,



Citação:
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????


Michael
   - 21 mar 2006

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


Renatacoimbra
   - 21 mar 2006

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:

#Código



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]).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.






Citação:


// Para Criar o Form Produtos

FForm := CriaForm.Nome(´Frm_Produtos´);
FForm.Show;




Depois eu uso apartir do cadastro de produtos para criar uma consulta:

#Código


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





Marco Salles
   - 21 mar 2006

O que voce tem que fazer é o seguinte

1) No form Principal declare FForm como Public 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 Implementation declare

na seccçao Public Um Variavel

#Código

public
FFormB : TForm;
{ Public declarations }


#Código
implementation

uses
FormFactoryU;


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

#Código
implementation
uses FormFactoryU,unitDoFormProduto,UnitDoFormPrincipal;


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


Para criar o FormConsulta atraves do FormProduto

#Código
FFormB := FormFactory.CreateForm(´FormConsulta´);
FFormB.ShowModal;
FreeAndNil(FFormB);


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

Por exemplo

#Código
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

#Código
If assigned(FormProduto) Then

Voce vera que é Nil.. Por isso as mensagens de acesso Violado que voce deve estar recebendo


Massuda
   - 21 mar 2006


Citação:
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.

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).


Marco Salles
   - 21 mar 2006


Citação:

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.


isto que eu quis dizer , quando deu o exemplo do Assigned


Citação:
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 form produto.. Pode ser no OnShow

#Código

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


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

:arrow: Na criação do FormCadastro , pode ser no OnShow

#Código
Tform(FormCadastro):=FormProduto.FFormB;


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

exemplo :

#Código
FormProduto.Edit1.text:=FormCadastro.Edit1.text;


Obs) Renata estas atribuiçoes tem que vir no OnShow antes de qualquer método , senão pode aparecer erros de acesso Violado


Citação:
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á


Massuda
   - 21 mar 2006


Citação:

Citação:
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?
Pensando bem, isso não tem muita relação com o problema. Por favor, desconsidere esse comentário.


Renatacoimbra
   - 21 mar 2006

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.