Classe Delphi
Classe Delphi
Classe Delphi
Vou
mostrar como criar uma classe do zero, e explicar o que o Delphi faz quando
usamos CTRL + SHIF + C ( Comando para implementar as propriedades e
Métodos de uma determinada classe ).
interface
Type
TCliente = class
private
protected
public
published
end;
implementation
end.
interface
Type
TCliente = class
private
protected
public
published
end;
implementation
end.
interface
Type
TCliente = class
private
protected
public
property ID :String;
property Nome :String;
property Sexo :String;
property CPF :String;
property RG :String;
property Telefone :String;
property Endereco :String;
property Bairro :String;
property Cidade :String;
property CEP :String;
published
end;
implementation
end.
Ao final da digitação da property CEP: String, iremos usar a combinação de
teclas CTRL + SHIF + C, para implementar a classe.
Seu código agora irá modificar complementa, incluindo várias procedures e
Fields. Vamos analisar como ficou o código.
unit uCliente;
interface
Type
TCliente = class
private
FNome: String;
FBairro: String;
FCEP: String;
FID: String;
FCPF: String;
FSexo: String;
FCidade: String;
FEndereco: String;
FTelefone: String;
FRG: String;
procedure SetBairro(const Value: String);
procedure SetCEP(const Value: String);
procedure SetCidade(const Value: String);
procedure SetCPF(const Value: String);
procedure SetEndereco(const Value: String);
procedure SetID(const Value: String);
procedure SetNome(const Value: String);
procedure SetRG(const Value: String);
procedure SetSexo(const Value: String);
procedure SetTelefone(const Value: String);
protected
public
property ID :String read FID write SetID;
property Nome :String read FNome write SetNome;
property Sexo :String read FSexo write SetSexo;
property CPF :String read FCPF write SetCPF;
property RG :String read FRG write SetRG;
property Telefone :String read FTelefone write SetTelefone;
property Endereco :String read FEndereco write SetEndereco;
property Bairro :String read FBairro write SetBairro;
property Cidade :String read FCidade write SetCidade;
property CEP :String read FCEP write SetCEP;
published
end;
implementation
{ TCliente }
end.
O que houve?
Para cada property criada, por exemplo: property ID :String; . O Delphi
criou 2 métodos de leitura(Read) e escrita(Write) : property ID :String
read FID write SetID; , onde:
FID = Field para armazenar o valor passado para propriedade
SetID = Procedure para validar por exemplo um ID já existe, ou então se o
CPF é válido, e logo em seguida atribuir o conteúdo informado para o Field
FID, veja como o Delphi implementa o SetID;
Com este método o parâmetro Const(não pode ser alterado dentro do método)
Value contém o valor informado quando usamos por exemplo :
Procedure TFrmCliente.Novo;
begin
Cliente.ID := 1;
End;
Sendo assim, o que este método SetID faz simplesmente é armazenar o Value
em FID, como a linha abaixo mostra :
FID := Value
Com isso temos uma suposta regra de negócios, onde o CPF tem que 14
caracteres, nem a mais, nem a menos. Voltando então a pergunta inicial,
temos regras de negocio nesta nossa classe de Cliente ? Inicialmente não ,
então não precisamos ter procedures SetID, SetNome,SetCPF,Set.... O que
vou fazer é bem simples , mas requer muita atenção. Inicialmente vamos
apagar todas as procedures declaradas e implementadas. Feito isso seu código
ficará assim :
unit uCliente;
interface
uses SysUtils;
Type
TCliente = class
private
FNome: String;
FBairro: String;
FCEP: String;
FID: String;
FCPF: String;
FSexo: String;
FCidade: String;
FEndereco: String;
FTelefone: String;
FRG: String;
{REMOVEMOS AS DECLARAÇÕES DAS PROCEDURES DAQUI }
protected
public
property ID :String read FID write SetID;
property Nome :String read FNome write SetNome;
property Sexo :String read FSexo write SetSexo;
property CPF :String read FCPF write SetCPF;
property RG :String read FRG write SetRG;
property Telefone :String read FTelefone write SetTelefone;
property Endereco :String read FEndereco write SetEndereco;
property Bairro :String read FBairro write SetBairro;
property Cidade :String read FCidade write SetCidade;
property CEP :String read FCEP write SetCEP;
published
end;
implementation
end.
interface
Type
TCliente = class
private
FNome: String;
FBairro: String;
FCEP: String;
FID: String;
FCPF: String;
FSexo: String;
FCidade: String;
FEndereco: String;
FTelefone: String;
FRG: String;
protected
public
{Observe que onde esta SetID, SetNome, Set... Foi modificado agora
para FID, FNome,F...}
published
end;
implementation
end.
Como vocês podem ver a Unit fica mais limpa, a classe fica bem mais
simples de se visualizar e dar manutenção, agora atenção, isso é se você não
tiver regras de negocio para suas propertys ok? Caso tenha você faz como o
Delphi implementa, cria a procedure, associa ela ao Write da property e
implementa ela com sua regra de negócio. Ficará então da seguinte forma com
a única regra de negocio que criamos, a do tamanho do CPF
unit uCliente;
interface
uses SysUtils;
Type
TCliente = class
private
FNome: String;
FBairro: String;
FCEP: String;
FID: String;
FCPF: String;
FSexo: String;
FCidade: String;
FEndereco: String;
FTelefone: String;
FRG: String;
protected
public
property ID :String read FID write FID;
property Nome :String read FNome write FNome;
property Sexo :String read FSexo write FSexo;
{Property CPF agora tem um mecanismo de validação para sua escrita}
property CPF :String read FCPF write SetCPF;
property RG :String read FRG write FRG;
property Telefone :String read FTelefone write FTelefone;
property Endereco :String read FEndereco write FEndereco;
property Bairro :String read FBairro write FBairro;
property Cidade :String read FCidade write FCidade;
property CEP :String read FCEP write FCEP;
published
end;
implementation
{ TCliente }
end.
Para usar sua classe e testar, faça o seguinte: crie um form e coloque um
BitBtn.
Precisamos dar Uses em uCliente para poder acessar a Classe TCliente. Feito
isso, no evento onClick do BitBtn, implemente o seguinte :
procedure TFrmCliente.BtnNovoClick(Sender: TObject);
Var
C: TCliente;
Begin
C := TCliente.Create;
C.Nome:= 'WESLEY YAMAZACK' ;
C.Bairro:= 'CENTRO' ;
C.CEP:= '216548-856 ' ;
C.ID:= '00005' ;
C.CPF := '123.456.789-100' ; // Deste jeito você vera o erro
C.CPF := '123.456.789-10' ; // Deste jeito irá funcionar
C.Sexo:= 'M' ;
C.Cidade:= 'RIO DE JANEIRO ' ;
C.Endereco:= 'RUA M, N 145, APTO 809' ;
C.Telefone:= '(21)3222-1111 ' ;
C.RG:= '12.313.214-1' ;
C.Free;
end;
POO e DAO Pattern no Delphi: Criando uma tela de login
Veja neste artigo como utilizar de maneira prá tica assuntos como Programaçã o Orientada a
comunidade Delphi.
Introdução
A POO (Programação Orientada a Objetos), cujos pilares básicos são: Herança,
Polimorfimo e Encapsulamento, é uma metodologia inteligente de desenvolvimento de
software, que visa tornar os sistemas mais flexiveis a mudanças, fáceis de manter, e
permite uma grande reutilização de código.
Para corrigir este problema, podemos utilizar a POO em conjunto com o Design
Pattern DAO.
O Padrão DAO (Data Access Object) é um pattern que permite separar acesso a dados e
regras de negócio da camada de apresentação, centralizando as responsabilidades de
manipulação do banco de dados e facilitando a manutenção.
O Delphi é uma linguagem de alto nível, compilada, fortemente tipada, que suporta os
paradigmas de programação estruturada e orientada a objetos, sendo uma excelente
ferramenta de desenvolvimento.
Para esse artigo foi utilizado o Delphi XE e banco de dados Firebird 2.5
Criação do Projeto
Crie um novo diretório, onde serão salvos o Banco de Dados (caso use
firebird/interbase) e os arquivos do Projeto.
Utilizando o Banco de Dados e o Front End de sua preferência, crie um novo banco e
execute os scripts abaixo para criação da tabela Usuarios, e o usuario administrador,
respectivamente:
Listagem 1: Scripts do Banco de Dados
Iremos utilizar a nova Unit para criação da classe TLoginModel, que será responsável
por transferir informações entre a camada de negócios e a camada de apresentação.
Respeitando as boas práticas de POO, não iremos expor publicamente nossos campos,
mas iremos encapsular o acesso a eles utilizando métodos getters, setters e propriedades.
unit uLoginModel;
interface
Type
TLoginModel = class
strict private
// campos
FUsuario: string;
FSenha: string;
// getters
// setters
public
// propriedades
end;
implementation
{ TLoginModel }
begin
Result := FSenha;
end;
begin
Result := FUsuario;
end;
begin
FSenha := Value;
end;
begin
FUsuario := Value;
end;
end.
3 Labels;
2 Edits;
2 Buttons.
Digite as informações da classe TLoginDAO, e não esqueça de dar uses nas Units
uLoginModel, DBXCommon, SysUtils.
unit uLoginDAO;
interface
type
TLoginDAO = class
public
end;
implementation
uses
Dialogs;
{ TLoginDAO }
function TLoginDAO.Logar(LoginModel: TLoginModel): Boolean;
var
begin
try
try
dbcon:=TDBXConnectionFactory.GetConnectionFactory.GetConnection('L
OGINOO',
'sysdba','masterkey');
sql := dbcon.CreateCommand;
parametro := sql.CreateParameter;
parametro.DataType := TDBXDataTypes.WideStringType;
parametro.Name := 'pUsuario';
sql.Parameters.AddParameter(parametro);
sql.Parameters.Parameter[0].Value.SetWideString(LoginModel.Usuario
);
parametro.DataType := TDBXDataTypes.WideStringType;
parametro.Name := 'pSenha';
sql.Parameters.AddParameter(parametro);
sql.Parameters.Parameter[1].Value.SetWideString(LoginModel.Senha);
Result := True;
except on E : Exception do
end;
finally
FreeAndNil(dbcon);
FreeAndNil(sql);
FreeAndNil(reader);
end;
end;
end.
LoginModel: TLoginModel;
LoginDAO: TLoginDAO;
begin
else
begin
try
LoginModel.Usuario := edtUsuario.Text;
LoginModel.Senha := edtSenha.Text;
begin
ShowMessage('Acesso Autorizado');
end
else
finally
FreeAndNil(LoginModel);
FreeAndNil(LoginDAO);
end;
end;
end;
begin
end;
POO na prática com Delphi - SimpleMasterDetail
Olá pessoal, neste artigo mostrarei de forma prática e direta como é fácil utilizar POO
no Delphi, criaremos uma classe para conexão e uma classe de clientes para realizar as
operações de Select, Insert, Update e Delete no banco. A POO (Programação Orientada
a Objetos) facilita e muito a manutenção e o reaproveitamento de código, sendo ainda
fácil de se entender e aplicar, vamos pôr a mão na massa?
Nome varchar(50),
Endereco varchar(50),
Telefones varchar(50),
Obs varchar(200) )
Tabela construída vamos agora para a construção de nossa classe de conexão, (File >
New > Unit). Nesta eu utilizei ADO, observe abaixo a unit uConn:
uses ADODB;
type
constructor TConn.Create;
begin
Conn := TADOConnection.Create(nil);
Conn.LoginPrompt := false;
Conn.ConnectionString := 'Provider=SQLOLEDB.1'+
';Password=XXXXX'+
';User ID=XXXXX'+
';Initial Catalog=Clientes'+
';Data Source=QD_08';
Agora vamos a classe de Clientes (File > New > Unit), observe abaixo a unit uClientes:
FNome: string;
FChave: integer;
FEndereco: string;
FTelefone: string;
FQry: TADOQuery;
FDs: TDataSource;
Conexao : TConn;
published public
// Componentes
// Métodos
' id = :id';
Parameters.ParamByName('id').Value := FChave;
Parameters.ParamByName('Nome').Value := Fnome;
Parameters.ParamByName('Endereco').Value := Fendereco;
Parameters.ParamByName('Telefones').Value := FTelefone;
end;
end;
end;
Conexao := Conn;
Qry := TADOQuery.Create(nil);
Ds := TDataSource.Create(nil);
QryPesquisa := TADOQuery.Create(nil);
DsPesquisa := TDataSource.Create(nil);
Qry.Connection := Conexao.Conn;
QryPesquisa.Connection := Conexao.Conn;
Parameters.ParamByName('Chave').Value := Chave;
try
end;
end;
end;
function TClientes.Inserir: boolean; begin with Qry do
begin
Close;
Parameters.ParamByName('Nome').Value := Fnome;
Parameters.ParamByName('Endereco').Value := Fendereco;
Parameters.ParamByName('Telefones').Value := FTelefone;
Parameters.ParamByName('Obs').Value := FObs;
try
except
result := false;
end;
end;
end;
begin
Nome := '%'+Nome+'%';
with QryPesquisa do
begin
Close;
Parameters.ParamByName('Chave').Value := Chave;
end;
try
Open;
else
Result := false;
except
Result := false;
end;
end;
end;
begin
begin
begin
begin
begin
FObs := Value; end;
begin
begin
Observem que esta classe é simples e só contém métodos com SQL, estes métodos são
usados na nossa tela. Na Figura 1 segue uma sugestão de layout para a tela.
Figura 1.
Sugestão de layout
Observe abaixo o código do formulário, note que no create do mesmo instanciei nossas
classes e já realizei um select para carregar o grid. Código da unit ufrmPrincipal:
uses
TfrmPrincipal = class(TForm)
PageControl1: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
TabSheet3: TTabSheet;
TabSheet4: TTabSheet;
Label1: TLabel;
DBNavigator1: TDBNavigator;
DBGrid1: TDBGrid;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
edtNome: TEdit;
edtEndereco: TEdit;
edtTelefone: TEdit;
mmoObs: TMemo;
Label6: TLabel;
Label7: TLabel;
Label8: TLabel;
Label9: TLabel;
BitBtn1: TBitBtn;
BitBtn2: TBitBtn;
mmoUPObs: TMemo;
edtUpTelefones: TEdit;
Label10: TLabel;
Label11: TLabel;
edtUpEndereco: TEdit;
Label12: TLabel;
Label13: TLabel;
edtUpNome: TEdit;
Label14: TLabel;
edtClienteDel: TEdit;
BitBtn3: TBitBtn;
Label15: TLabel;
Y: Integer);
procedure LimpaCampos;
public
var
frmPrincipal: TfrmPrincipal;
Conn : TConn;
Clientes : TClientes;
{$R *.dfm}
Nome := edtNome.text;
Endereco := edtEndereco.text;
begin
end
else
begin
end;
end;
LimpaCampos; end;
Chave :=
DBGrid1.DataSource.DataSet.FieldByName('id').AsInteger;
Nome := edtUpNome.text;
Endereco := edtUpEndereco.text;
Telefone := edtUpTelefones.text;
Obs := mmoUpObs.Text;
begin
else
begin
end;
end;
LimpaCampos; end;
if
clientes.Deletar(DBGrid1.DataSource.DataSet.FieldByName('id').asintege
r)then
begin
end else
begin
end;
LimpaCampos; end;
edtUpNome.text :=
DBGrid1.DataSource.DataSet.FieldByName('Nome').asstring;
edtUpEndereco.text :=
DBGrid1.DataSource.DataSet.FieldByName('Endereco').asstring;
edtUpTelefones.text :=
DBGrid1.DataSource.DataSet.FieldByName('telefones').asstring;
mmoUPObs.Text :=
DBGrid1.DataSource.DataSet.FieldByName('Obs').asstring;
edtClienteDel.text :=
DBGrid1.DataSource.DataSet.FieldByName('Nome').asstring; end;
procedure TfrmPrincipal.DBGrid1DblClick(Sender: TObject); begin
DBGrid1.DataSource := clientes.DsPesquisa;
DBNavigator1.DataSource:= Clientes.DsPesquisa;
//Conn.Destroy; end;
end; end;
frmSplashSobre := TfrmSplashSobre.create(application);
frmSplashSobre.ShowModal;
finally
freeandnil(frmSplashSobre);
end;
end;
end.
Master Detail
Agora mostraremos uma relação simples “Master Detail” com POO no Delphi. Para
isso vamos construir nossa tabela de Compras, vejam o código:
Produto varchar(50),
Observações: Como foi usado o SQL server 2005, o id é auto incremento. Além disso,
tudo foi definido como varchar para facilitar e agilizar a construção do exemplo. Não é
a forma correta, mas foi a mais rápida.
Tendo em mente que você viu o artigo anterior, neste vou implementar apenas a classe
de Compras (ou vendas, fique à vontade), FILE > NEW > UNIT. Observe o código da
nossa unituCompras:
unit uCompras;
FChave: integer;
FChaveCliente: integer;
FValor: string;
FProduto: string;
FData: string;
FQry: TADOQuery;
FQryPesquisa: TADOQuery;
FDs: TDataSource;
// Propriedades
// ou Real
// ou TDatetime
// Componentes
// Métodos
begin
Close;
' id = :id';
Parameters.ParamByName('id').Value := FChave;
Parameters.ParamByName('Produto').Value := FProduto;
Parameters.ParamByName('Valor').Value := FValor;
Parameters.ParamByName('Data').Value := FData;
Parameters.ParamByName('idCliente').Value := ChaveCliente;
try
Conexao := Conn;
Qry := TADOQuery.Create(nil);
Ds := TDataSource.Create(nil);
QryPesquisa := TADOQuery.Create(nil);
DsPesquisa := TDataSource.Create(nil);
Qry.Connection := Conexao.Conn;
QryPesquisa.Connection := Conexao.Conn;
Ds.DataSet := Qry;
begin
Parameters.ParamByName('Chave').Value := Chave;
try
begin Close;
Parameters.ParamByName('Produto').Value := FProduto;
Parameters.ParamByName('Valor').Value := FValor;
Parameters.ParamByName('Data').Value := FData;
Parameters.ParamByName('idCliente').Value := ChaveCliente;
try
except
result := false;
end;
end; end;
function TCompras.Selecionar(Chave,ChaveCliente: Integer; Produto,
Ordem: String): Boolean; begin
Parameters.ParamByName('Chave').Value := Chave;
end;
Parameters.ParamByName('ChaveCliente').Value := ChaveCliente;
end;
try
Open;
begin
FData := Value; end;
begin
end.
Notem que é tudo muito igual ao primeiro artigo, os métodos de SQL têm o mesmo
nome, são as operações básicas do dia a dia, com esta classe criada vamos agora para
criação da nossa tela, o frmPrincipal, onde teremos dois dbgrids um para exibir o cliente
e outro para exibir as compras feitas pelo mesmo, observe abaixo o código
da unit ufrmPrincipal:
uses
type
TfrmPrincipal = class(TForm)
DBGridMaster: TDBGrid;
DBGridDetail: TDBGrid;
Label1: TLabel;
Label2: TLabel;
DBNavMaster: TDBNavigator;
DBNavDetail: TDBNavigator;
private
public
end;
var
frmPrincipal: TfrmPrincipal;
Conn : TConn;
Cliente := TClientes.Create(Conn);
Cliente.Selecionar(0,'','Nome');
DBGridMaster.DataSource := Cliente.DsPesquisa;
DBNavMaster.DataSource := Cliente.DsPesquisa;
if
Compra.Deletar(DBGridDetail.DataSource.DataSet.FieldByName('id').AsInt
eger) then begin
// refresh no grid
Compra.Selecionar(0,DBGridMaster.DataSource.DataSet.fieldbyname('id').
AsInteger,'','Produto
');
end;
Compra.Selecionar(0,DBGridMaster.DataSource.DataSet.fieldbyname('id').
AsInteger,'','Produto
');
end;
try
finally
Observem que não estamos usando ainda a separação das camadas que é altamente
recomendável, mas como este é um exemplo para introdução a POO no Delphi usamos
aqui apenas a persistência e a tela, facilitando assim o aprendizado.
Seguindo então vamos criar um form para “realizar as vendas conforme o código
da unitufrmInsereCompra:
unit ufrmInsereCompra;
interface
uses
type
RgProdutos: TRadioGroup;
var
frmInsereCompra: TfrmInsereCompra;
{$R *.dfm}
0 : begin
end; 2 : begin
ChaveCliente :=
Cliente.DsPesquisa.DataSet.fieldbyname('id').asinteger;
if Inserir then // operação incluir
begin
end; end;
Compra.Selecionar(0,frmPrincipal.DBGridMaster.DataSource.DataSet.field
byname('id').AsInteg er,'','Produto'); end;
begin
lblClienteSelecionado.Caption :=
Cliente.DsPesquisa.DataSet.fieldbyname('Fantasia').asstring; end; end.