用户输入时要面对许多Edit控件,每一个Edit控件对应数据库中的一个字段,现在要对每个Edit过行检查,但检查的规则大不一样,有些是不能为0的,有些是日期不能大于或小于某个日期的,有些是不能为空的,有些是要根据别的字段值来判断的,如A字段值为1的话,那B字段值就不能为2或3,诸如此类...
如何对这些规则进行设计,使得它符合OO的思想?

解决方案 »

  1.   

    是不是可以这样?
      TErrMsg = class
      private
         function 规则1:Boolean ;
         function 规则2:Boolean ;
           ....
         fnuction 规则n:boolean;
      end;  但是这些检查规则在检查时如果发现不合规则的值就要出现提示信息,那是不是就要把它设计成一个异常类?
      

  2.   

    定义规则类型,可以类,可以是集合,或者是记录,都行,
    每个EDIT设定不同规则,控制检查都用一个类来进行整的检查.
      

  3.   

    设计的大原则是这样:将行记录(TMyRecord)作为一个对象, 然后将对象映射到GUI(如:每个字段(属性)映射到相应的EDIT). 数据有效性的检测不在GUI中进行, 可以在TMyRecord中进行,或者建立一个TValidationVisitor(有效性访问者)MVP模式GUI(View)<--->Presenter<--->ModelEDITName<--->Presenter<--->TMyRecord.NameTMyRecord.Validation --->TValidationVisitor(TMyRecord).........上面只是简单的描述,具体的设计有许多工作
      

  4.   

    呵呵,多谢sanmaotuo(老冯) ,等您的实例
      

  5.   

    我下面的示范代码省略了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;-------------------
      

  6.   

    ----------------{ 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;