Aplicações Robustas III: Criação de Exceções
Esse artigo é continuação do post “Robustez no Delphi”
Dando continuidade a seqüência de artigos sobre tratamento de exceções.....
Com base em tudo o que foi falado nos artigos anteriores sobre exceções vamos tratar agora sobre como e por que criar suas próprias exceções. Entenda que não me refiro a levantar um exceção, quando uso o termo “criar” estou falando de definir uma classe nova, derivada diretamente de Exception, ou de um de seus herdeiros.
Criando suas próprias exceções:
Imagine uma situação em que a lógica do negócio envolvida no seu programa, defina certas regras que não podem ser quebradas. Você não vai encontrar nas bibliotecas do Delphi nenhuma exceção para o caso de um cliente ser cadastrado com valor para data de nascimento maior que a data corrente, por exemplo. Portanto, quando você precisa garantir que as regras pertinentes ao negócio sejam suportadas pelo seu sistema em forma de exceções é preciso para isso definir classes, tipos, de exceções específicas para isso.
Construindo um exemplo.
Para exemplificar, vamos propor um problema para em seguida implementarmos um pequeno programa, em cima desse problema, de maneira que possamos modelar as regrar contidas no domínio do problema em questão em forma de exceções.
O problema:
O programa que vamos contruir simula um pequeno aspecto da relação de uma farmácia e seus clientes. Vejamos, para compra de qualquer remédio controlado é exigido a apresentação, por parte do cliente, de uma receita válida para o remédio específico desejado. Em nosso exemplo vamos trabalhar com os seguintes atributos da receita: Data de validade e substância (remédio). Criaremos, portanto, duas classes de exceções: EDataInvalida (caso a receita esteja vencida), ESubstanciaErrada. Vamos arbitrariamente definir que a validade de uma receita seja de 4 dias. Já temos algumas regras, agora já podemos construir nosso pequeno programa.
O programa que vamos contruir simula um pequeno aspecto da relação de uma farmácia e seus clientes. Vejamos, para compra de qualquer remédio controlado é exigido a apresentação, por parte do cliente, de uma receita válida para o remédio específico desejado. Em nosso exemplo vamos trabalhar com os seguintes atributos da receita: Data de validade e substância (remédio). Criaremos, portanto, duas classes de exceções: EDataInvalida (caso a receita esteja vencida), ESubstanciaErrada. Vamos arbitrariamente definir que a validade de uma receita seja de 4 dias. Já temos algumas regras, agora já podemos construir nosso pequeno programa.
Inicie uma nova aplicação no Delphi: Menu, File ►New ► Application.
No Form1 adicione os seguintes componentes: Duas ComboBox (TComboBox), um Button (TButton), três Labels (TLabel) e um ListBox (TListBox), da palheta Standard; Um DateTimePicker1 (TDateTimePicker), da palheta Win32. Configure as propriedades dos componentes segundo listado abaixo:
Form1: Width = 470 Height = 494 Caption = 'Criando Exceções' Label1: Left = 12 Top = 12 Caption = 'Receita' Label2: Left = 300 Top = 12 Caption = 'Remédio' Label3: Left = 12 Top = 58 Caption = 'Data da Receita' ComboBox1: Name = CmbReceita Left = 12 Top = 29 Width = 280 ComboBox2: Name = CmbRemedio Left = 300 Top = 29 Width = 150 Button1: TButton Left = 373 Top = 64 Width = 75 Height = 25 Caption = 'Efetuar venda' ListBox1: Name = LstVendas Left = 12 Top = 104 Width = 445 Height = 353 DateTimePicker1: Name = DtReceita Left = 12 Top = 75 Width = 82
A seção type da unit1 deverá estar assim
type TForm1 = class(TForm) CmbReceita: TComboBox; CmbRemedio: TComboBox; Button1: TButton; ListBox1: TListBox; DtReceita: TDateTimePicker; Label1: TLabel; Label2: TLabel; Label3: TLabel; private { Private declarations } public { Public declarations } end;
Logo abaixo da palavra reservada “type” vamos codificar a definição das nossas exceções. Faça conforme exemplo abaixo:
type EDataInvalida = class(Exception);//Exceção para data inválida ESubstanciaErrada = class(Exception); // Exceção de substância errada TForm1 = class(TForm) CmbReceita: TComboBox; CmbRemedio: TComboBox; Button1: TButton; LstVendas: TListBox; DtReceita: TDateTimePicker; Label1: TLabel; Label2: TLabel; Label3: TLabel; private procedure LoadReceitas; procedure LoadRemedios; procedure CriticarVenda; { após digitar as procedures a cima pressione: “Ctrl+Shift+C”} public { Public declarations } end;
Codificaremos primeiro o preenchimento da combo com os remédios.
procedure TForm1.LoadRemedios; begin (* Montando a combo dos remédios *) with CmbRemedio do begin Items.Add('Frontal'); Items.Add('Tefxel'); Items.Add('Lorax'); Items.Add('Haldol'); Items.Add('Urbanil'); Items.Add('Tagretol'); end; end;
Em seguida o preenchimento da combo das receitas. Para facilitarmos nosso exemplo vamos ordenar as receitas conforme a ordem dos remédios.
procedure TForm1.LoadReceitas; const DescReceita = 'Receita para o remédio: %s'; var i: Integer; begin for i := 0 to CmbRemedio.Items.Count - 1) do CmbReceita.Items.Add(Format(DescReceita, [CmbRemedio.Items[i]])) end;
Agora, a rotina que gera as exeções, “CriticarVenda”.
procedure TForm1.CriticarVenda; begin (* Caso nehuma opção seja selecionada levantaremos uma exceção genérica*) if (CmbReceita.ItemIndex < 0) and (CmbRemedio.ItemIndex < 0) then raise Exception.Create('Selecione a receita, em seguida o remédio.'); (* Caso uma opção não seja selecionada levantaremos a exceção que criamos*) if (CmbReceita.ItemIndex <= 0) xor (CmbRemedio.ItemIndex <= 0) then raise ESubstanciaErrada.Create('A receita não corresponde ao remédio.'); (* Caso as opção selecionada sejam diferntes *) if not (CmbReceita.ItemIndex = CmbRemedio.ItemIndex ) then raise ESubstanciaErrada.Create('A receita não corresponde ao remédio.'); (* definimos, hipoteticamente, prazo de validade de 6 dias para a receita. *) if DtReceita.Date < (Date - 6) then raise EDataInvalida.Create('Prazo de validade da receita expirou.'); end;
No evento OnCreate do From1 faremos a chamada aos procedimentos que preencherão as Combos.
procedure TForm1.FormCreate(Sender: TObject); begin LoadRemedios; LoadReceitas; DtReceita.Date := Date - 10; end;
Para finalizar, o evento OnClick do Button1, onde construiremos o tratamento das exceções.
procedure TForm1.Button1Click(Sender: TObject); const MsgSucesso = 'Venda efetuada com sucesso: %s'; begin try CriticarVenda; LstVendas.Items.Add(Format(MsgSucesso, [CmbRemedio.Text])); except on E: EDataInvalida do LstVendas.Items.Add(E.Message); on E: ESubstanciaErrada do begin LstVendas.Items.Add(E.Message); CmbRemedio.SetFocus; if CmbReceita.ItemIndex < 0 then begin MessageBox(0, 'Selecione a receita.', 'Criando Exceções - Estação ZN', MB_ICONERROR or MB_OK); CmbReceita.SetFocus; end; end; on E: Exception do begin MessageBox(0, PChar(E.Message), 'Criando Exceções - Estação ZN', MB_ICONERROR or MB_OK); CmbReceita.SetFocus; end; end; end;
Veja as imagens abaixo:



Nenhum comentário:
Postar um comentário