function TMinhaClasse.GetSumVr_Contabil: Double;
var
CloneItems: TClientDataSet;
begin
Result:= 0;
CloneItems := TClientDataSet.Create(nil);
try
CloneItems.CloneCursor(MeuDataSet, True);
while not CloneItems.eof do
begin
Result := Result + CloneItems.FieldByName('vr_contabil').AsFloat;
CloneItems.Next;
end;
finally
CloneItems.Free;
end;
end;
function TMinhaClasse.GetSumVr_Desconto: Double;
var
CloneItems: TClientDataSet;
begin
Result:= 0;
CloneItems := TClientDataSet.Create(nil);
try
CloneItems.CloneCursor(MeuDataSet, True);
while not CloneItems.eof do
begin
Result := Result + CloneItems.FieldByName('vr_desconto').AsFloat;
CloneItems.Next;
end;
finally
CloneItems.Free;
end;
end;
Bem, este caso é muito simples. Portanto, a resposta parece óbvia: cria-se um novo método para o qual passamos como parâmetro o nome do campo a ser sumarizado. É verdade. Mas se o processamento envolvesse mais do que uma simples linha de código, a resposta poderia ser bem diferente. Como proceder? Usar delegação (em delphi, ponteiro para uma função).
Declaramos o tipo de função que esperamos receber como parâmetro na função que fará o processamento:
type
TCalcFunc = function (const Value: Double; DataSet: TDataSet): Double of object;
Criamos um novo método com toda a lógica do processamento. E este método receberá como parâmetro um ponteiro para a função que irá fazer o processamento. Isto eliminará a duplicação de código, reduzindo a possibilidade de erros advindos de alterações na lógica (Não é raro esquecermos de alterar o código copiado/colado):
function TMinhaClasse.GetSum(CalcFunc: TCalcFunc): Double;
var
CloneItems: TClientDataSet;
begin
Result:= 0;
CloneItems := TClientDataSet.Create(nil);
try
CloneItems.CloneCursor(MeuDataSet, True);
CloneItems.First;
while not CloneItems.Eof do
begin
Result := CalcFunc(Result, CloneItems);
CloneItems.Next;
end;
finally
CloneItems.Free;
end;
end;
Agora modificamos as funcões antigas para adaptá-las à nova metodologia:
function TMinhaClasse.GetSumVr_Contabil: Double;
begin
Result := GetSum(CalcVrContabil);
end;
function TMinhaClasse.GetSumVr_Desconto: Double;
begin
Result := GetSum(CalcVrDesconto);
end;
function TMinhaClasse.CalcVrContabil(const Value: Double; DataSet: TDataSet): Double;
begin
Result := Value + DataSet.FieldByName('vr_contabil').AsFloat;
end;
function TMinhaClasse.CalcVrDesconto(const Value: Double; DataSet: TDataSet): Double;
begin
Result := Value + DataSet.FieldByName('vr_desconto').AsFloat;
end;
Agora ficou fácil adicionar novas funções aproveitando a mesma lógica: GetSumVr_Frete(), GetSumVr_ICMS(), etc.
Outra maneira de fazer a mesma coisa seria usando design patterns. Mas, às vezes a coisa é tão simples que aplicar um ou vários design patterns seria como usar um martelo para matar uma formiguinha, levando a um excesso de sofisticação na engenharia.
Aguardo os seus comentários e críticas. Ok?
Um comentário:
Vo tentar fazer esse exemplo ai na prática; Ei maxu...num daria pra tu botar as "strings" de uma cor diferente nao?! Ficaria melhor de ler o exemplo...
Postar um comentário