如何用OO的思想设计此种情况? 用户输入时要面对许多Edit控件,每一个Edit控件对应数据库中的一个字段,现在要对每个Edit过行检查,但检查的规则大不一样,有些是不能为0的,有些是日期不能大于或小于某个日期的,有些是不能为空的,有些是要根据别的字段值来判断的,如A字段值为1的话,那B字段值就不能为2或3,诸如此类...如何对这些规则进行设计,使得它符合OO的思想? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 是不是可以这样? TErrMsg = class private function 规则1:Boolean ; function 规则2:Boolean ; .... fnuction 规则n:boolean; end; 但是这些检查规则在检查时如果发现不合规则的值就要出现提示信息,那是不是就要把它设计成一个异常类? 定义规则类型,可以类,可以是集合,或者是记录,都行,每个EDIT设定不同规则,控制检查都用一个类来进行整的检查. 设计的大原则是这样:将行记录(TMyRecord)作为一个对象, 然后将对象映射到GUI(如:每个字段(属性)映射到相应的EDIT). 数据有效性的检测不在GUI中进行, 可以在TMyRecord中进行,或者建立一个TValidationVisitor(有效性访问者)MVP模式GUI(View)<--->Presenter<--->ModelEDITName<--->Presenter<--->TMyRecord.NameTMyRecord.Validation --->TValidationVisitor(TMyRecord).........上面只是简单的描述,具体的设计有许多工作 呵呵,多谢sanmaotuo(老冯) ,等您的实例 我下面的示范代码省略了PRESENTER ,不过还是很长. 慢慢看吧unit Model.EmployeeIntf; IEmployee = interface(IVisited) ['{09128A11-80C2-4403-A111-BEEC5BC0FD49}'] function GetID: string; procedure SetID(const Value: string); function GetName: string; procedure SetName(const Value: string); function GetAge: Integer; procedure SetAge(const Value: Integer); function GetGender: string; procedure SetGender(const Value: string); property ID: string read GetID write SetID; property Name: string read GetName write SetName; property Age: Integer read GetAge write SetAge; property Gender: string read GetGender write SetGender; procedure SaveToPersistent; end;unit Model.EmployeeImpl; TEmployee = class(TInterfacedObject, IEmployee) private FID: string; FName: string; FAge: Integer; FGender: string; protected //IEmployee function GetID: string; procedure SetID(const Value: string); function GetName: string; procedure SetName(const Value: string); function GetAge: Integer; procedure SetAge(const Value: Integer); function GetGender: string; procedure SetGender(const Value: string); procedure SaveToPersistent; //IVisited procedure Accept(const Visitor: IVisitor); public end;unit GUI.EditForm TGUIEditForm = class(TForm) PnlEmployeeID: TRzPanel; EdtEmployeeID: TRzEdit; PnlEmployeeName: TRzPanel; EdtEmployeeName: TRzEdit; PnlEmployeeGender: TRzPanel; EdtEmployeeGender: TRzEdit; PnlEmployeeAge: TRzPanel; EdtEmployeeAge: TRzEdit; ActionList1: TActionList; AcSave: TAction; procedure AcSaveExecute(Sender: TObject); private FModel: IEmployee; FState: TEditState; procedure MapFromModel; procedure MapToModel; procedure SetControl; public constructor Create(const Model: IEmployee; State: TEditState); reintroduce; end; implementation{ TGUIEditForm }constructor TGUIEditForm.Create(const Model: IEmployee; State: TEditState);begin inherited Create(nil); Assert(FModel <> nil, '无效的Model参数'); FModel := Model; FState := State; MapFromModel; SetControl;end;procedure TGUIEditForm.MapFromModel;begin EdtEmployeeID.Text := FModel.ID; EdtEmployeeName.Text := FModel.Name; EdtEmployeeAge.Text := IntToStr(FModel.Age); EdtEmployeeGender.Text := FModel.Gender;end;procedure TGUIEditForm.MapToModel;begin FModel.ID := EdtEmployeeID.Text; FModel.Name := EdtEmployeeName.Text; FModel.Age := StrToInt(EdtEmployeeAge.Text); FModel.Gender := EdtEmployeeGender.Text;end;procedure TGUIEditForm.SetControl;begin //Enable/Disable Controls ReadOnly.end;procedure TGUIEditForm.AcSaveExecute(Sender: TObject);begin FModel.SaveToPersistent;end;unit BusinessValidation;TEmployeeValidationVisitor = class(TInterfacedObject, IVisitor) private procedure IDValidation; procedure NameValidation; procedure AgeValidation; procedure GenderValidation; protected //IVisitor procedure Visit(const Visited: IInterface); public end;implementation{ TEmployeeValidationVisitor }procedure TEmployeeValidationVisitor.Visit(const Visited: IInterface);var Obj: IEmployee;begin Visited.QueryInterface(IEmployee, Obj); if Obj <> nil then begin IDValidation; NameValidation; AgeValidation; GenderValidation; end;end;procedure TEmployeeValidationVisitor.AgeValidation;begin //Do Your Validation Check raise EAgeException.Create(EAgeMessage);end;procedure TEmployeeValidationVisitor.GenderValidation;begin //Do Your Validation Check raise EGenderException.Create(EGenderMessage);end;procedure TEmployeeValidationVisitor.IDValidation;begin //Do Your Validation Check raise EIDException.Create(EIDMessage);end;procedure TEmployeeValidationVisitor.NameValidation;begin //Do Your Validation Check raise ENameException.Create(ENameMessage);end;unit BusinessPersistent;type TEmployeePersistentVisitor = class(TInterfacedObject, IVisitor) private protected //IVisitor procedure Visit(const Visited: IInterface); public end;implementation{ TEmployeePersistentVisitor }procedure TEmployeePersistentVisitor.Visit(const Visited: IInterface);var Obj: IEmployee;begin Visited.QueryInterface(IEmployee, Obj); if Obj <> nil then begin {Do Your Persistent Work} end;end;unit Exception;interfaceuses SysUtils;const EIDMessage = '您输入的ID不符合规则'; ENameMessage = '您输入的姓名不符合规则'; EAgeMessage = '您输入的年龄不符合规则'; EGenderMessage = '您输入的性别不符合规则';type EIDException = Exception; ENameException = Exception; EAgeException = Exception; EGenderException = Exception;------------------- ----------------{ TEmployee }procedure TEmployee.Accept(const Visitor: IVisitor);begin Visitor.Visit(Self);end;function TEmployee.GetAge: Integer;begin Result := FAge;end;function TEmployee.GetGender: string;begin Result := FGender;end;function TEmployee.GetID: string;begin Result := FID;end;function TEmployee.GetName: string;begin Result := FName;end;procedure TEmployee.SaveToPersistent;var Visitor: IVisitor;begin Visitor := TEmployeeValidationVisitor.Create; Self.Accept(Visitor); Visitor := TEmployeePersistentVisitor.Create; Self.Accept(Visitor);end;procedure TEmployee.SetAge(const Value: Integer);begin FAge := Value;end;procedure TEmployee.SetGender(const Value: string);begin FGender := Value;end;procedure TEmployee.SetID(const Value: string);begin FID := Value;end;procedure TEmployee.SetName(const Value: string);begin FName := Value;end; 判斷文本框為空怎樣寫代碼 使用Access数据库,居然查询有错,MSSQL就不会 关于AdoQuery的指针问题 500分求解问题,得道高手请进吧。 同志们,你们在编写程序的时候,都是先画流程图的吗 书 各位DELPHI大侠,你们用DELPHI做开发,用的是中文版还是英文版? 一直可以用的QQ,现在总是不能登陆——提示密码错误(密码肯定是正确的),是被人黑了吗?怎么可以找回密码?…………有什么办法可能可再用这个QQ! 如何删除IE的历史纪录 今晚有多少人通宵? 请问,DBGrid中如何设置显示自动列宽? 动态连接库调用
TErrMsg = class
private
function 规则1:Boolean ;
function 规则2:Boolean ;
....
fnuction 规则n:boolean;
end; 但是这些检查规则在检查时如果发现不合规则的值就要出现提示信息,那是不是就要把它设计成一个异常类?
每个EDIT设定不同规则,控制检查都用一个类来进行整的检查.
['{09128A11-80C2-4403-A111-BEEC5BC0FD49}']
function GetID: string;
procedure SetID(const Value: string);
function GetName: string;
procedure SetName(const Value: string);
function GetAge: Integer;
procedure SetAge(const Value: Integer);
function GetGender: string;
procedure SetGender(const Value: string);
property ID: string read GetID write SetID;
property Name: string read GetName write SetName;
property Age: Integer read GetAge write SetAge;
property Gender: string read GetGender write SetGender;
procedure SaveToPersistent;
end;unit Model.EmployeeImpl; TEmployee = class(TInterfacedObject, IEmployee)
private
FID: string;
FName: string;
FAge: Integer;
FGender: string;
protected
//IEmployee
function GetID: string;
procedure SetID(const Value: string);
function GetName: string;
procedure SetName(const Value: string);
function GetAge: Integer;
procedure SetAge(const Value: Integer);
function GetGender: string;
procedure SetGender(const Value: string);
procedure SaveToPersistent;
//IVisited
procedure Accept(const Visitor: IVisitor);
public
end;unit GUI.EditForm TGUIEditForm = class(TForm)
PnlEmployeeID: TRzPanel;
EdtEmployeeID: TRzEdit;
PnlEmployeeName: TRzPanel;
EdtEmployeeName: TRzEdit;
PnlEmployeeGender: TRzPanel;
EdtEmployeeGender: TRzEdit;
PnlEmployeeAge: TRzPanel;
EdtEmployeeAge: TRzEdit;
ActionList1: TActionList;
AcSave: TAction;
procedure AcSaveExecute(Sender: TObject);
private
FModel: IEmployee;
FState: TEditState;
procedure MapFromModel;
procedure MapToModel;
procedure SetControl;
public
constructor Create(const Model: IEmployee; State: TEditState); reintroduce;
end; implementation{ TGUIEditForm }constructor TGUIEditForm.Create(const Model: IEmployee; State: TEditState);
begin
inherited Create(nil);
Assert(FModel <> nil, '无效的Model参数');
FModel := Model;
FState := State;
MapFromModel;
SetControl;
end;procedure TGUIEditForm.MapFromModel;
begin
EdtEmployeeID.Text := FModel.ID;
EdtEmployeeName.Text := FModel.Name;
EdtEmployeeAge.Text := IntToStr(FModel.Age);
EdtEmployeeGender.Text := FModel.Gender;
end;procedure TGUIEditForm.MapToModel;
begin
FModel.ID := EdtEmployeeID.Text;
FModel.Name := EdtEmployeeName.Text;
FModel.Age := StrToInt(EdtEmployeeAge.Text);
FModel.Gender := EdtEmployeeGender.Text;
end;procedure TGUIEditForm.SetControl;
begin
//Enable/Disable Controls ReadOnly.
end;procedure TGUIEditForm.AcSaveExecute(Sender: TObject);
begin
FModel.SaveToPersistent;
end;unit BusinessValidation;TEmployeeValidationVisitor = class(TInterfacedObject, IVisitor)
private
procedure IDValidation;
procedure NameValidation;
procedure AgeValidation;
procedure GenderValidation;
protected
//IVisitor
procedure Visit(const Visited: IInterface);
public
end;implementation{ TEmployeeValidationVisitor }procedure TEmployeeValidationVisitor.Visit(const Visited: IInterface);
var
Obj: IEmployee;
begin
Visited.QueryInterface(IEmployee, Obj);
if Obj <> nil then
begin
IDValidation;
NameValidation;
AgeValidation;
GenderValidation;
end;
end;procedure TEmployeeValidationVisitor.AgeValidation;
begin
//Do Your Validation Check
raise EAgeException.Create(EAgeMessage);
end;procedure TEmployeeValidationVisitor.GenderValidation;
begin
//Do Your Validation Check
raise EGenderException.Create(EGenderMessage);
end;procedure TEmployeeValidationVisitor.IDValidation;
begin
//Do Your Validation Check
raise EIDException.Create(EIDMessage);
end;procedure TEmployeeValidationVisitor.NameValidation;
begin
//Do Your Validation Check
raise ENameException.Create(ENameMessage);
end;unit BusinessPersistent;type
TEmployeePersistentVisitor = class(TInterfacedObject, IVisitor)
private
protected
//IVisitor
procedure Visit(const Visited: IInterface);
public
end;implementation{ TEmployeePersistentVisitor }procedure TEmployeePersistentVisitor.Visit(const Visited: IInterface);
var
Obj: IEmployee;
begin
Visited.QueryInterface(IEmployee, Obj);
if Obj <> nil then
begin
{Do Your Persistent Work}
end;
end;unit Exception;interfaceuses
SysUtils;const
EIDMessage = '您输入的ID不符合规则';
ENameMessage = '您输入的姓名不符合规则';
EAgeMessage = '您输入的年龄不符合规则';
EGenderMessage = '您输入的性别不符合规则';type
EIDException = Exception;
ENameException = Exception;
EAgeException = Exception;
EGenderException = Exception;-------------------
begin
Visitor.Visit(Self);
end;function TEmployee.GetAge: Integer;
begin
Result := FAge;
end;function TEmployee.GetGender: string;
begin
Result := FGender;
end;function TEmployee.GetID: string;
begin
Result := FID;
end;function TEmployee.GetName: string;
begin
Result := FName;
end;procedure TEmployee.SaveToPersistent;
var
Visitor: IVisitor;
begin
Visitor := TEmployeeValidationVisitor.Create;
Self.Accept(Visitor);
Visitor := TEmployeePersistentVisitor.Create;
Self.Accept(Visitor);
end;procedure TEmployee.SetAge(const Value: Integer);
begin
FAge := Value;
end;procedure TEmployee.SetGender(const Value: string);
begin
FGender := Value;
end;procedure TEmployee.SetID(const Value: string);
begin
FID := Value;
end;procedure TEmployee.SetName(const Value: string);
begin
FName := Value;
end;