就是太长了,我分几次贴吧,高手给指导指导unit Cls_DataFactory;interface{  本单元定义了系统配置类、ADO数据访问抽象类,基于ADO的 ms sql server
   实体类,以及数据访问工厂,其中ADO数据访问类是一个产品族,在工厂方法
   的基础上可以扩展如: acces,oracle等等能以ADO进行访问的产品。
   注意:数据访问抽象类接口仅仅支持SQL
 }uses db, adodb, SysUtils, Classes;type   {系统配置类}
   TConfig = class(TObject)
   private
     Fallname: string;
     Fsimplename: string;
     Ftelephone: string;
     Faddress: string;
     Fhomepage: string;
     Femail: string;
     Fsvrname: string;
     Fdatabase: string;
     Fuser: string;
     Fpassword: string;
     function getallname: string;
     procedure setallname(value: string);
     function getsimplename: string;
     procedure setsimplename(value: string);
     function gettelephone: string;
     procedure settelephone(value: string);
     function getaddress: string;
     procedure setaddress(value: string);
     function gethomepage: string;
     procedure sethomepage(value: string);
     function getemail: string;
     procedure setemail(value: string);
     function getsvrname: string;
     procedure setsvrname(value: string);
     function getdatabase: string;
     procedure setdatabase(value: string);
     function getuser: string;
     procedure setuser(value: string);
     function getpassword: string;
     procedure setpassword(value: string);
     procedure loadconfig(fn: string);
   public
     constructor create;
     procedure saveconfig(fn: string);
     property allname: string read getallname write setallname;
     property simplename: string read getsimplename write setsimplename;
     property telephone: string read gettelephone write settelephone;
     property address: string read getaddress write setaddress;
     property homepage: string read gethomepage write sethomepage;
     property email: string read getemail write setemail;
     property svrname: string read getsvrname write setsvrname;
     property database: string read getdatabase write setdatabase;
     property user: string read getuser write setuser;
     property password: string read getpassword write setpassword;
   end;   {抽象数据访问类}
   TAbsAdoManager = class(Tdatamodule)
   protected
     FConfig: TConfig;
     Connector: TAdoConnection;
     function getconfig: TConfig;  virtual; abstract;
     procedure setconfig(value: TConfig); virtual; abstract;
     function getconnstring: string; virtual; abstract;
   public
     function  StartConnection: boolean; virtual; abstract;
     procedure EndConnection; virtual; abstract;
     function GetDbList: Tstrings; virtual; abstract;
     procedure ExecuteSQL(SQL: string); virtual; abstract;
     function  GetDataSet(SQL: string): TDataSet; virtual; abstract;
     property  Config: TConfig read getconfig write setconfig;
   end;   TAdoSqlManager = class(TAbsAdoManager)
   protected
     FConfig: TConfig;
     Connector: TAdoConnection;
     function getconfig: TConfig; override;
     procedure setconfig(value: TConfig); override;
     function getconnstring: string; override;
   public
     constructor Create(AOwner: TComponent); override;
     destructor Destory;
     function  StartConnection: boolean; override;
     procedure EndConnection; override;
     function GetDbList: Tstrings; override;
     procedure ExecuteSQL(SQL: string); override;
     function  GetDataSet(SQL: string): TDataSet; override;
     property  Config: TConfig read getconfig write setconfig;
   end;   { 工厂方法 }
   TDataFactory = class(TObject)
   public
     function CreateAdoSqlManager(AOwner: TComponent): TAdoSqlManager;
     //下面尚未定义的数据访问类的工厂方法
     //function CreateAdoAccessManager(AOwner: TComponent): TAdoSqlManager;
     //function CreateAdoOracleManager(AOwner: TComponent): TAdoSqlManager;
   end;

解决方案 »

  1.   


    implementationuses  inifiles;{ 配置文件中的口令加解密}function Encrypt(value: string): string;
    begin
      result:= value;
    end;function Decrypt(value: string): string;
    begin
      result:= value;
    end;{ Sql server 访问类实现 }constructor TAdoSqlManager.Create(AOwner: TComponent);
    begin
      inherited;
      try
        FConfig:= TConfig.create;
        Connector:= TAdoConnection.Create(AOwner);
      except
      end;
    end;
    function TAdoSqlManager.StartConnection: boolean;
    begin
      result:= false;
      try
        EndConnection;
        if not Connector.Connected then
        begin
          Connector.ConnectionString:= getconnstring;
        end;
        Connector.Open;
        result:= Connector.Connected;
      except
        exit;
      end;
    end;procedure TAdoSqlManager.EndConnection;
    begin
      inherited;
      Connector.Close;
    end;procedure TAdoSqlManager.ExecuteSQL(SQL: string);
    var
      TempCommand: TAdoCommand;
    begin
      inherited;
      TempCommand:= TAdoCommand.Create(nil);
      try
        TempCommand.CommandText:= SQL;
        Tempcommand.Execute;
      finally
        TempCommand.Free;
      end;
    end;function TAdoSqlManager.GetDataSet(SQL: string): TDataSet;
    var
      TempDataSet: TAdoquery;
    begin
      TempDataSet:= TAdoquery.Create(nil);
      try
        TempDataSet.Connection:= Connector;
        TempDataSet.SQL.Add(SQL);
        TempDataSet.Open;
      except
      end;
      result:= TempDataSet;
    end;destructor TAdoSqlManager.Destory;
    begin
      Connector.Free;
      inherited;
    end;function TAdoSqlManager.getconfig: TConfig;
    begin
      result:= Fconfig;
    end;procedure TAdoSqlManager.setconfig(value: TConfig);
    begin
     Fconfig:= value;
    end;function TAdoSqlManager.GetDbList: Tstrings;
    var
      dblist: Tstrings;
      TempDataSet: TAdoquery;
    begin
      dblist:= Tstringlist.Create;
      TempDataSet:= TAdoquery.Create(nil);
      try
        TempDataSet.Connection:= Connector;
        TempDataSet.SQL.Add('exec sp_databases');
        TempDataSet.Open;
        while not TempDataSet.Eof do
        begin
          dblist.Add(TempDataSet.fieldbyname('DATABASE NAME').AsString);
          TempDataSet.Next;
        end;
      finally
        TempDataSet.Free;
      end;
      result:= dblist;
    end;
      

  2.   


    { 系统配置类实现 }constructor TConfig.create;
    begin
      try
       loadconfig('config.ini');
      except
      end;
    end;function TConfig.getaddress: string;
    begin
      result:= Faddress;
    end;function TConfig.getallname: string;
    begin
      result:= Fallname;
    end;function TConfig.getdatabase: string;
    begin
      result:= Fdatabase;
    end;function TConfig.getemail: string;
    begin
      result:= Femail;
    end;function TConfig.gethomepage: string;
    begin
      result:= Fhomepage;
    end;function TConfig.getpassword: string;
    begin
      result:= fpassword;
    end;function TConfig.getsimplename: string;
    begin
      result:= Fsimplename;
    end;function TConfig.getsvrname: string;
    begin
      result:= fsvrname;
    end;function TConfig.gettelephone: string;
    begin
      result:= Ftelephone;
    end;function TConfig.getuser: string;
    begin
      result:= fuser;
    end;function TAdoSqlManager.getconnstring: string;
    begin
      result:= 'Provider=SQLOLEDB.1;';
      result:= result + 'Persist Security Info=False;';
      result:= result + 'Initial Catalog=' + FConfig.Fdatabase + ';';
      result:= result + 'User Id=' + FConfig.FUser + ';';
      result:= result + 'Password=' + FConfig.Fpassword + ';';
      result:= result + 'Data Source=' + FConfig.Fsvrname;
    end;procedure TConfig.loadconfig(fn: string);
    var
      inifile: Tinifile;
    begin
      inifile:= Tinifile.Create(fn);
      try
        Fallname:= inifile.ReadString('Application','allname','');
        Fsimplename:= inifile.ReadString('Application','simplename','');
        Ftelephone:= inifile.ReadString('Application','telephone','');
        Faddress:= inifile.ReadString('Application','address','');
        Fhomepage:= inifile.ReadString('Application','homepage','');
        Femail:= inifile.ReadString('Application','email','');
        Fsvrname:= inifile.ReadString('ADO','svrname','127.0.0.1');
        Fdatabase:= inifile.ReadString('ADO','database','master');
        Fuser:= inifile.ReadString('ADO','user','guest');
        Fpassword:= Decrypt(inifile.ReadString('ADO','password',''));
      finally
        inifile.Free;
      end;
    end;procedure TConfig.saveconfig(fn: string);
    var
      inifile: Tinifile;
    begin
      inifile:= Tinifile.Create(fn);
      try
        inifile.WriteString('Application','allname',Fallname);
        inifile.WriteString('Application','simplename',Fsimplename);
        inifile.WriteString('Application','telephone',Ftelephone);
        inifile.WriteString('Application','address',Faddress);
        inifile.WriteString('Application','homepage',Fhomepage);
        inifile.WriteString('Application','email',Femail);
        inifile.WriteString('ADO','svrname',Fsvrname);
        inifile.WriteString('ADO','database',Fdatabase);
        inifile.WriteString('ADO','user',Fuser);
        inifile.WriteString('ADO','password',Encrypt(Fpassword));
      finally
        inifile.Free;
      end;
    end;procedure TConfig.setaddress(value: string);
    begin
      Faddress:= value;
    end;procedure TConfig.setallname(value: string);
    begin
      Fallname:= value;
    end;procedure TConfig.setdatabase(value: string);
    begin
      Fdatabase:= value;
    end;procedure TConfig.setemail(value: string);
    begin
      Femail:= value;
    end;procedure TConfig.sethomepage(value: string);
    begin
      Fhomepage:= value;
    end;procedure TConfig.setpassword(value: string);
    begin
     Fpassword:= value;
    end;procedure TConfig.setsimplename(value: string);
    begin
      Fsimplename:= value;
    end;procedure TConfig.setsvrname(value: string);
    begin
      Fsvrname:= value;
    end;procedure TConfig.settelephone(value: string);
    begin
      Ftelephone:= value;
    end;procedure TConfig.setuser(value: string);
    begin
      Fuser:= value;
    end;{ 工厂实现 }function TDataFactory.CreateAdoSqlManager(AOwner: TComponent): TAdoSqlManager;
    begin
      result:= TAdoSqlManager.Create(AOwner);
    end;end.
      

  3.   

    { 抽象工厂 }
       TAbsDataFactory = class(TObject)
       public
         function CreateManager(AOwner: TComponent): TAbsAdoManager;
       end;   TAdoSqlFactory = class(TAbsDataFactory)
       public
         function CreateManager(AOwner: TComponent): TAbsAdoManager;
       end;
      

  4.   

    只看这一个就够了:   TDataFactory = class(TObject)
       public
         function CreateAdoSqlManager(AOwner: TComponent): TAdoSqlManager;
       end;毛病一,你声明的抽象类TAbsAdoManager,不直接做返回值,却用了TAdoSqlManager。这是何故?而后面搞了一个TAdoSqlFactory多余的东西来用。又是何故?一个工厂模式别名叫虚构造机。毛病二,工厂模式,也要管调用的是哪个构造方法。你现在有一个构造方法,用一个类来管理,然后针对每个构造方法派生出许多管理类。但是有N个你怎么办?难道调用N个方法???N个工厂类,生成N个管理类。尽管你这个例子中,数据连接是屈指可数的,但不用忘了,它叫:设计模式。是通用的。要对接口编程,不能对实现编程!工厂有一个,产品可以有N个。但是你现在的状况有N个工厂来制造N个对应的产品。这就算工厂模式?好了,其他的我不再多说了。再看看,再学学…… 问一下:你看了GOF的书了吗?
      

  5.   

    没有所谓的TAdoSqlFactory,没有所谓的TAdoAccessFactory,没有所谓的TAdoOracleFactory只有一个!那就是TAdoFactory。
      

  6.   

    重写了一下,看看还有毛病没有?
     {抽象数据访问类}
       TAbsAdoManager = class(Tdatamodule)
       public
         function  StartConnection: boolean; virtual; abstract;
         procedure EndConnection; virtual; abstract;
         function GetDbList: Tstrings; virtual; abstract;
         procedure ExecuteSQL(SQL: string); virtual; abstract;
         function  GetDataSet(SQL: string): TDataSet; virtual; abstract;
       end;   TAdoSqlManager = class(TAbsAdoManager)
       private
         Connector: TAdoConnection;
         function getconnstring: string;
       public
         constructor Create(AOwner: TComponent); override;
         destructor Destory;
         function  StartConnection: boolean; override;
         procedure EndConnection; override;
         function GetDbList: Tstrings; override;
         procedure ExecuteSQL(SQL: string); override;
         function  GetDataSet(SQL: string): TDataSet; override;
       end;   { 抽象工厂 }
       TAbsDataFactory = class(TObject)
       public
         function CreateManager(AOwner: TComponent): TAbsAdoManager; virtual; abstract;
       end;   TAdoSqlFactory = class(TAbsDataFactory)
       public
         function CreateManager(AOwner: TComponent): TAbsAdoManager; override;
       end;   //下面定义尚未实现的数据访问类的工厂方法
       {
       TAdoAccessFactory = class(TAbsDataFactory)
       public
         function CreateManager(AOwner: TComponent): TAbsAdoManager; override;
       end;   TAdoOracleDataFactory = class(TAbsDataFactory)
       public
         function CreateManager(AOwner: TComponent): TAbsAdoManager; override;
       end;
       }
      

  7.   

    另外,提醒你。你的virtual; abstract;别随便用。谨慎一些。
      

  8.   

    为什么现在的高手的这么吝啬,哎...
    不过,先谢谢了 reallike(爱翔)