Design Parttern (Singleton / Factory / DAO)
Boa tarde
Estou começando a desenvolver orientado a objetos no Delphi 2009, e estou implementando o padrão DAO para persistência de dados. Encontrei pouquíssimo material sobre o assunto na internet, e estou me baseando no material de Ricardo Coelho na edição 115 onde fala muito bem sobre o assunto.
Fiz o exemplo dele, e quase tudo estava funcionando, só fiz algumas correções de sintaxe. O botão alterar, e excluir estão funcionando, exceto o de incluir, quando tento incluir algo recebo uma exceção. Depurei a o erro acontece exatamente no código abaixo. Que erro é este?
Tentei atribuir o código do usuário para o novo cliente desta forma TCliente(pCliente).UsuarioCadastro.Id := 1; , mas também não funcionou. Tenho que instanciar o usuário no meu formulário?
Grato Denivaldo Junior ----------------------------------- Evento OnClick do botão Novo:
Cliente := TCliente.Create;
Cliente.State := sdNew;
BtnGravar.Enabled := true;
BtnCancelar.Enabled := True;
BtnExcluir.Enabled := false;
BtnEditar.Enabled := false;
BtnNovo.Enabled := false;
Evento OnClick do botão Gravar:
ViewToModel(Cliente);
if(Cliente.State = sdNew)then
begin
Cliente.UsuarioCadastro := TAplicacao.GetInstance.UsuarioLogado;
Dao.Insert(cliente);
end
else if(Cliente.State = sdEdit)then
Dao.Update(cliente);
Procedure ViewToModel:
pCliente.Id := StrToInt(edtID.Text);
pCliente.Nome := edtNome.Text;
pCliente.Idade := StrToInt(edtIdade.Text);
pCliente.Bairro := EdtBairro.Text;
pCliente.DiaCadastro := DateOf(now);
pCliente.HoraCadastro := TimeOf(now);
Procedimento Insert da Classe ClienteDao
procedure TClienteDao.Insert(pCliente:TBaseDomain);
var Qry:TSQLQuery;
Transacao : TDBXTransaction;
begin
Qry := TSQLQuery.Create(nil);
Qry.SQLConnection := TConexaoBD.GetInstance.ConexaoBD;
try
Transacao := Qry.SQLConnection.BeginTransaction;
Qry.SQL.Add('INSERT INTO CLIENTE(ID, NOME, IDADE, BAIRRO, ID_USUARIO) VALUES ');
Qry.SQL.Add('(:pID, :pNOME, :pIDADE, :pBAIRRO, :pID_USUARIO)');
Qry.ParamByName('pID').AsInteger := TCliente(pCliente).ID;
Qry.ParamByName('pNOME').AsString := TCliente(pCliente).Nome;
Qry.ParamByName('pIDADE').AsInteger := TCliente(pCliente).Idade;
Qry.ParamByName('pBAIRRO').AsString := TCliente(pCliente).Bairro;
>> Qry.ParamByName('pID_USUARIO').AsInteger := TCliente(pCliente).UsuarioCadastro.Id;;
Qry.ExecSQL();
pCliente.State := sdBrowse;
Qry.SQLConnection.CommitFreeAndNil(Transacao);
except
Qry.SQLConnection.RollbackFreeAndNil(Transacao);
Application.MessageBox('Um erro aconteceu operação cancelada!', 'ERRO!', MB_APPLMODAL + MB_ICONEXCLAMATION + MB_OK+MB_DEFBUTTON1);
end;
end;
Grato Denivaldo Junior ----------------------------------- Evento OnClick do botão Novo:
Cliente := TCliente.Create;
Cliente.State := sdNew;
BtnGravar.Enabled := true;
BtnCancelar.Enabled := True;
BtnExcluir.Enabled := false;
BtnEditar.Enabled := false;
BtnNovo.Enabled := false;
Evento OnClick do botão Gravar:
ViewToModel(Cliente);
if(Cliente.State = sdNew)then
begin
Cliente.UsuarioCadastro := TAplicacao.GetInstance.UsuarioLogado;
Dao.Insert(cliente);
end
else if(Cliente.State = sdEdit)then
Dao.Update(cliente);
Procedure ViewToModel:
pCliente.Id := StrToInt(edtID.Text);
pCliente.Nome := edtNome.Text;
pCliente.Idade := StrToInt(edtIdade.Text);
pCliente.Bairro := EdtBairro.Text;
pCliente.DiaCadastro := DateOf(now);
pCliente.HoraCadastro := TimeOf(now);
Procedimento Insert da Classe ClienteDao
procedure TClienteDao.Insert(pCliente:TBaseDomain);
var Qry:TSQLQuery;
Transacao : TDBXTransaction;
begin
Qry := TSQLQuery.Create(nil);
Qry.SQLConnection := TConexaoBD.GetInstance.ConexaoBD;
try
Transacao := Qry.SQLConnection.BeginTransaction;
Qry.SQL.Add('INSERT INTO CLIENTE(ID, NOME, IDADE, BAIRRO, ID_USUARIO) VALUES ');
Qry.SQL.Add('(:pID, :pNOME, :pIDADE, :pBAIRRO, :pID_USUARIO)');
Qry.ParamByName('pID').AsInteger := TCliente(pCliente).ID;
Qry.ParamByName('pNOME').AsString := TCliente(pCliente).Nome;
Qry.ParamByName('pIDADE').AsInteger := TCliente(pCliente).Idade;
Qry.ParamByName('pBAIRRO').AsString := TCliente(pCliente).Bairro;
>> Qry.ParamByName('pID_USUARIO').AsInteger := TCliente(pCliente).UsuarioCadastro.Id;;
Qry.ExecSQL();
pCliente.State := sdBrowse;
Qry.SQLConnection.CommitFreeAndNil(Transacao);
except
Qry.SQLConnection.RollbackFreeAndNil(Transacao);
Application.MessageBox('Um erro aconteceu operação cancelada!', 'ERRO!', MB_APPLMODAL + MB_ICONEXCLAMATION + MB_OK+MB_DEFBUTTON1);
end;
end;
Denivaldo Junior
Curtidas 0
Respostas
Wesley Yamazack
14/04/2010
Olá amigo, foi até bom você ter comentado sobre o DAO, vou fazer umas quick tips sobre DAO.
Agora voltando a sua dúvida, qual seria o erro ?
Um abraço
Wesley Y
Agora voltando a sua dúvida, qual seria o erro ?
Um abraço
Wesley Y
GOSTEI 0
Denivaldo Junior
14/04/2010
Olá
Primeiramente se puder postar algum artigo sobre DAO vai ser de grande utilidade.
O erro é "Access violation at address 0048512C in module apoo.exe. write of address 00004".
Se eu passar um inteiro para query abaixo funciona.
Qry.ParamByName('pID_USUARIO').AsInteger := 1;
Acho que é na hora que ele busca o ID do usuário.
Obrigado desde já pela atenção.
Denivaldo Junior
Primeiramente se puder postar algum artigo sobre DAO vai ser de grande utilidade.
O erro é "Access violation at address 0048512C in module apoo.exe. write of address 00004".
Se eu passar um inteiro para query abaixo funciona.
Qry.ParamByName('pID_USUARIO').AsInteger := 1;
Acho que é na hora que ele busca o ID do usuário.
Obrigado desde já pela atenção.
Denivaldo Junior
GOSTEI 0
Wesley Yamazack
14/04/2010
Olá amigo,
O Access Violation só acontece em duas situações.
1 - Você esta tentando acessar um Objeto, que não foi criado.
2- Você esta tentando acessar um Objeto, que já foi destruido.
Depurando o código qual é a linha que da o erro ? Esta que você mandou ?
Um abraço
Wesley Y
O Access Violation só acontece em duas situações.
1 - Você esta tentando acessar um Objeto, que não foi criado.
2- Você esta tentando acessar um Objeto, que já foi destruido.
Depurando o código qual é a linha que da o erro ? Esta que você mandou ?
Um abraço
Wesley Y
GOSTEI 0
Denivaldo Junior
14/04/2010
Sim, foi esta linha.
Segundo o exemplo, no evento on click do botão INSERIR, o objeto cliente é criado. Acho que falta criar o usuário: Como faço isso?, o exemplo que estou usando é o mesmo que consta na revista 115 da clube delphi de ricardo coelho.
Evento OnClick do botão Novo:
Cliente := TCliente.Create;
Segundo o exemplo, no evento on click do botão INSERIR, o objeto cliente é criado. Acho que falta criar o usuário: Como faço isso?, o exemplo que estou usando é o mesmo que consta na revista 115 da clube delphi de ricardo coelho.
Evento OnClick do botão Novo:
Cliente := TCliente.Create;
GOSTEI 0
Wesley Yamazack
14/04/2010
Olá amigo,
Você poderia me mandar o seu código fonte para poder analisar ? Utilize o DiscoVirtual para isso.
Um abraço
Wesley Y
Você poderia me mandar o seu código fonte para poder analisar ? Utilize o DiscoVirtual para isso.
Um abraço
Wesley Y
GOSTEI 0
Denivaldo Junior
14/04/2010
Ok, já está lá.
Obrigado
Obrigado
GOSTEI 0
Wesley Yamazack
14/04/2010
Olá amigo, você tem que me passar o link pois eu não tenho acesso ao seu disco virtual, me mande o link para download.
Um abraço
Wesley Y
Um abraço
Wesley Y
GOSTEI 0
Denivaldo Junior
14/04/2010
http://video.devmedia.com.br/discovirtual/65275/POO (SINGLETON FACTORY
DAO).rar
GOSTEI 0
Wesley Yamazack
14/04/2010
Olá amigo, estou analisando o chamado, observei que você não esta criando o usuario na classe cliente, isso você terá que fazer.
Agora uma coisa, você conhece o padrão singleton ? Se sim poderia criar um usuario singleton, seria mais pratico, e não precisaria instanciar toda hora o usuário.
Segunda dúvida, qual motivo da propriedade Usuario na classe Cliente ?
Um abraço
Wesley Y
Agora uma coisa, você conhece o padrão singleton ? Se sim poderia criar um usuario singleton, seria mais pratico, e não precisaria instanciar toda hora o usuário.
Segunda dúvida, qual motivo da propriedade Usuario na classe Cliente ?
Um abraço
Wesley Y
GOSTEI 0
Denivaldo Junior
14/04/2010
Não conheço bem padrão singleton, estou estudando, e achei que neste exemplo estava sendo usando o singleton, pois o título da matéria de Ricardo Coelho era "singleton / factory / dao".
1. Como faria isto através do singleton? Poderia mandar um exemplo?
2. O objetivo do "usuário" no cliente é associar o usuário que fez o login através da classe TUsuário.
Ou seja, usuario ADM logou, então este mesmo usuário deve estar associado ao novo cliente para saber quem o cadastrou.
Att
Denivaldo Jr
1. Como faria isto através do singleton? Poderia mandar um exemplo?
2. O objetivo do "usuário" no cliente é associar o usuário que fez o login através da classe TUsuário.
Ou seja, usuario ADM logou, então este mesmo usuário deve estar associado ao novo cliente para saber quem o cadastrou.
Att
Denivaldo Jr
GOSTEI 0
Wesley Yamazack
14/04/2010
Olá amigo, para entender melhor o que é um singleton, baixe esta video aula do amigo Rodrigo Carreiro,
https://www.devmedia.com.br/post-11809-Rad-Studio-2007-DBX4-e-Firebird-2-0-Aplicacao-comercial-de-vendas-do-Inicio-ao-Fim-Parte-24-Padrao-de-Projeto-Singleton.html
Nela você irá ver passa a passo como criar um singleton.
Você disse : 2. O objetivo do "usuário" no cliente é associar o usuário que fez o login através da classe TUsuário.
Com o Singleton você só terá uma instancia do usuário na sua aplicação, com isso o seu usuário já terá referencia, e valores atribuídos como usuário e senha.
Espero que isso lhe ajude.
Um abraço
Wesley Y
https://www.devmedia.com.br/post-11809-Rad-Studio-2007-DBX4-e-Firebird-2-0-Aplicacao-comercial-de-vendas-do-Inicio-ao-Fim-Parte-24-Padrao-de-Projeto-Singleton.html
Nela você irá ver passa a passo como criar um singleton.
Você disse : 2. O objetivo do "usuário" no cliente é associar o usuário que fez o login através da classe TUsuário.
Com o Singleton você só terá uma instancia do usuário na sua aplicação, com isso o seu usuário já terá referencia, e valores atribuídos como usuário e senha.
Espero que isso lhe ajude.
Um abraço
Wesley Y
GOSTEI 0
Denivaldo Junior
14/04/2010
Ok, já vi o padrão singleton. Mas preciso descobrir o erro?
Att
Denivaldo Junior
Att
Denivaldo Junior
GOSTEI 0
Wesley Yamazack
14/04/2010
Olá amigo,
Se você descobriu o singleton, você verá que não teria como dar access violation, pois você não esta criando o usuáriologado : tusuario na class cliente, você tem que criar o usuário na hora que criar a classe cliente.
Ou seja implemente o oncreate do cliente, e nele crie o usuário novamente, já que você quer fazer assim, apesar de não estar no padrão. Sacou ?
Um abraço
Wesley Y
Se você descobriu o singleton, você verá que não teria como dar access violation, pois você não esta criando o usuáriologado : tusuario na class cliente, você tem que criar o usuário na hora que criar a classe cliente.
Ou seja implemente o oncreate do cliente, e nele crie o usuário novamente, já que você quer fazer assim, apesar de não estar no padrão. Sacou ?
Um abraço
Wesley Y
GOSTEI 0
Wesley Yamazack
14/04/2010
Olá amigo,
Eu não consegui resolver teu problema ? lhe ajudar ? Esclarecer tua dúvida ? Você quer realmente resolver o problema do access violation ? Não quer fazer o Singleton da maneira correta ? Se for isso sem problemas eu resolvo o access violation .
Fico no aguardo
Att,
Wesley Y
Eu não consegui resolver teu problema ? lhe ajudar ? Esclarecer tua dúvida ? Você quer realmente resolver o problema do access violation ? Não quer fazer o Singleton da maneira correta ? Se for isso sem problemas eu resolvo o access violation .
Fico no aguardo
Att,
Wesley Y
GOSTEI 0
Denivaldo Junior
14/04/2010
Na verdade acho que o Ricardo tinha criado apenas a classe de conexão no padrão singleton.
Não sei qual foi o padrão da classe TUsuario e TCLiente. Mas apliquei o padrão singleton na classe TUsuario, de forma que corrigi o problema na inserção da seguinte forma:
Classe TClienteDao
Qry.ParamByName('pID_USUARIO').AsInteger := TUsuario.GetInstance.Id;
Desculpe se marquei como não resolvido, é porque como estou aprendendo oop na prática, fiquei curioso em saber porque estava dando violação de acesso. Se era algum erro de sintaxe ou onde estava deixando de criar o usuário, ou quem sabe onde eu estava destruindo o objeto, pois como você respondeu, esse erro só dá quando um objeto já foi destruído ou não foi criado.
Mas enfim, o problema foi resolvido sim. Obrigado pelas dicas e pela atenção.
Com certeza vou postar mais dúvidas, porque esse exemplo de padrão DAO / Singleton foi apenas um ponta pé pra comecar meu sistema.
Sabe de alguma video aula sobre o padrão factory? Preciso identificar ele neste exemplo.
Att
Denivaldo Junior
Não sei qual foi o padrão da classe TUsuario e TCLiente. Mas apliquei o padrão singleton na classe TUsuario, de forma que corrigi o problema na inserção da seguinte forma:
Classe TClienteDao
Qry.ParamByName('pID_USUARIO').AsInteger := TUsuario.GetInstance.Id;
Desculpe se marquei como não resolvido, é porque como estou aprendendo oop na prática, fiquei curioso em saber porque estava dando violação de acesso. Se era algum erro de sintaxe ou onde estava deixando de criar o usuário, ou quem sabe onde eu estava destruindo o objeto, pois como você respondeu, esse erro só dá quando um objeto já foi destruído ou não foi criado.
Mas enfim, o problema foi resolvido sim. Obrigado pelas dicas e pela atenção.
Com certeza vou postar mais dúvidas, porque esse exemplo de padrão DAO / Singleton foi apenas um ponta pé pra comecar meu sistema.
Sabe de alguma video aula sobre o padrão factory? Preciso identificar ele neste exemplo.
Att
Denivaldo Junior
GOSTEI 0
Wesley Yamazack
14/04/2010
Olá amigo,
quanto ao curso o único que tenho para lhe indicar seria este do renato matos e que depois meu amigo rodrigo carreiro, assumiu https://www.devmedia.com.br/cursos/listcurso.asp?curso=120, porém não tem exatamente os padrões de projetos como você quer, mas senão me engano, esta para sair uma série de padrões seria interessante derrepente você esperar sair as videos, blz ?
Em relação ao chamado estou fechando o mesmo agora, e aguardo mais dúvidas.
Um abraço
Wesley Y
quanto ao curso o único que tenho para lhe indicar seria este do renato matos e que depois meu amigo rodrigo carreiro, assumiu https://www.devmedia.com.br/cursos/listcurso.asp?curso=120, porém não tem exatamente os padrões de projetos como você quer, mas senão me engano, esta para sair uma série de padrões seria interessante derrepente você esperar sair as videos, blz ?
Em relação ao chamado estou fechando o mesmo agora, e aguardo mais dúvidas.
Um abraço
Wesley Y
GOSTEI 0