设计目的:由于每次在操作数据库的时候都要对数据的合法性验证,每次都是很麻烦的编写过程,要么类中反复的实现Validate方法。工作都是重复性的,而且每次验证的内容都大致的相同,大致有是否是数字的验证,数字最大值和最小值的验证,文字长度的验证,日期的验证。因此就有个想法把所有的验证都封装起来,这样既便于维护又便于调试,精简了代码,简化了业务,充分体现了类封装性。
那么如何来实现呢?我们先来看看还没有封装雏形的实现,这个Demo主要解决了类的通用性的问题,使我们的Tvalidate能够适应所有的可编辑类型组件。包括TcxEdit、TcomboBox、Tedit、cxMaskEdit等所有从TwinControl继承下来的组件。
rel="File-List" href="file:///C:%5CDOCUME%7E1%5CYUCHEN%7E1.SPE%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_filelist.xml"> rel="themeData" href="file:///C:%5CDOCUME%7E1%5CYUCHEN%7E1.SPE%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_themedata.thmx"> rel="colorSchemeMapping" href="file:///C:%5CDOCUME%7E1%5CYUCHEN%7E1.SPE%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_colorschememapping.xml">
unit svmValidate;
interface
uses
Classes, svmUtils, SysUtils, Controls;
type
{ TvalidType is valid type
vtNull: defined as emptystr or ‘’ will return true.
vtNumber: Indicates whether a specified number value occurs on number.
vtDate: indicates whether a specified year, month, and day represent a valid
date.
vtMax: Indicates whether a maximize value for vtNumber.
vtMin: Indicates whether a minimize value for vtNumber.
vtPath: Indicates whether a valid path. }
TvalidType = (vtNull, vtNumber, vtMax, vtMin, vtDate, vtDateMax,
vtDateMin, vtPath);
{ Describe a class and show error information
Component must be an instance of the class denoted by TwinControl or one of
its descendants }
PvalidRec = ^TvalidRec;
TvalidRec = record
Name: string;
Component: TwinControl;
ValidType: TvalidType;
Value: Extended;
ErrorInfo: string;
end;
EvalidExcept = class(Exception);
TtempWinControl = class(TwinControl);
{ this is a validate class, be used for data validate }
TcustomValid = class(Tobject)
private
FvalidList: TstringList;
protected
function Find(Name: string): ustaph;
public
constructor Create; virtual;
destructor Destroy; override;
procedure Register(Acomponent: TwinControl; AvalidType: TvalidType;
Avalue: Extended; AerrorInfo: string); virtual;
procedure UnRegister(Aname: string); virtual;
function Validate: ustaph; virtual;
procedure Clear; virtual;
end;
Tvalid = class(TcustomValid);
resourcestring
sErrNull = ‘%s cannot be NULL or an empty value.’;
sErrMax = ‘%s must less than to the maximum value (%f).’;
sErrMin = ‘%s must larger than to the minimum value (%f).’;
sErrNum = ‘%s must be number.’;
sErrDate = ‘%s must be DateTime.’;
sErrValid = ‘%d’;
sErrPath = ‘%s is not a valid path.’;
implementation
{ TcustomValid }
procedure TcustomValid.Clear;
var
i: integer;
begin
for i := FvalidList.Count – 1 downto 0 do
dispose(PvalidRec(FvalidList.Objects[i]));
FvalidList.Clear;
end;
constructor TcustomValid.Create;
begin
inherited;
FvalidList := TstringList.Create;
end;
destructor TcustomValid.Destroy;
begin
Clear;
FvalidList.Free;
inherited;
end;
function TcustomValid.Validate: ustaph;
var
i: integer;
vErrorMsg: string;
Value: Extended;
vErrorInfo: string;
vValidType: TvalidType;
vText: string;
f: Extended;
d: TdateTime;
begin
result := false;
if FvalidList.Count = 0 then
exit;
for i := 0 to FvalidList.Count – 1 do
begin
Value := PvalidRec(FvalidList.Objects[i])^.Value;
vErrorInfo := PvalidRec(FvalidList.Objects[i])^.ErrorInfo;
vValidType := PvalidRec(FvalidList.Objects[i])^.ValidType;
vText := TtempWinControl(PvalidRec(FvalidList.Objects[i]).Component).Text;
case vValidType of
vtNull:
begin
result := trim(vText) = ‘’;
vErrorMsg := Format(sErrNull, [vErrorInfo]);
end;
vtNumber:
begin
result := not TryStrToFloat(vText, f);
vErrorMsg := Format(sErrNum, [vErrorInfo]);
end;
vtDate:
begin
result := not TryStrToDateTime(vText, d);
vErrorMsg := Format(sErrDate, [vErrorInfo]);
end;
vtMax:
begin
result := (StrToFloat(vText) >= Value);
vErrorMsg := Format(sErrMax, [vErrorInfo, Value]);
end;
vtMin:
begin
result := (StrToFloat(vText) <= Value);
vErrorMsg := Format(sErrMin, [vErrorInfo, Value]);
end;
vtPath:
begin
result := not ValidatePath(vText);
vErrorMsg := Format(sErrPath, [vErrorInfo]);
end;
end;
if result then
begin
try
TtempWinControl(PvalidRec(FvalidList.Objects[i]).Component).SetFocus;
ErrorMsg(vErrorMsg);
break;
except
raise EvalidExcept.CreateFmt(sErrValid, [result]);
end;
end;// if end
end;// for end
end;
function TcustomValid.Find(Name: string): ustaph;
begin
result := FvalidList.IndexOf(Name) > 0;
end;
procedure TcustomValid.Register(Acomponent: TwinControl; AvalidType: TvalidType;
Avalue: Extended; AerrorInfo: string);
var
Pvalid: PvalidRec;
vName: string;
begin
New(Pvalid);
vName := Acomponent.Name + IntToStr(Ord(AvalidType));
Pvalid^.Name := Acomponent.Name;
Pvalid^.Component := Acomponent;
Pvalid^.ValidType := AvalidType;
Pvalid^.Value := Avalue;
Pvalid^.ErrorInfo := AerrorInfo;
FvalidList.AddObject(vName, Pointer(Pvalid));
end;
procedure TcustomValid.UnRegister(Aname: string);
var
vIndex: integer;
begin
vIndex := FvalidList.IndexOf(Aname);
if vIndex > 0 then
begin
Dispose(PvalidRec(FvalidList.Objects[vIndex]));
FvalidList.Delete(vIndex);
end;
end;
end.