//我想创建一个dao接口,用2个类实现它,客户端调用时,生成DAO接口,传入相关类的参数,就能调用,用Delphi如何写?
类1
package com.Test.userdao;public interface Userdao { public void savedata();
}类2
package com.Test.userdao;public class SqlserverDAOImpl implements Userdao { public void savedata() {
// TODO Auto-generated method stub
System.out.println("SqlserverDAOImpl");
}}类3
package com.Test.userdao;public class OracleDAOImpl implements Userdao { public void savedata() {
// TODO Auto-generated method stub
System.out.println("OracleDAOImpl");
}}
客户端
package com.Test.client;import com.Test.userdao.OracleDAOImpl;
import com.Test.userdao.Userdao;
public class Clienttest { private Userdao userdao;
    public Clienttest(Userdao userdao){
     this.userdao=userdao;
    
    }

    public void Mytest(){
     userdao.savedata();
    
    }
 public static void main(String[] args) {
Clienttest clienttest1=new Clienttest(new OracleDAOImpl());
clienttest1.Mytest();
}
}

解决方案 »

  1.   


    //DAO接口
    unit Unit2;
    interface
    type
      IUserDAO=interface
      ['{30E0E943-37B7-43B9-9C4B-CAA9150F3CC7}']
        procedure SaveData();stdcall;
      end;
    implementation
    end.
    //实现类1
    unit Unit3;
    interface
     uses
      sysutils, dialogs, classes,  unit2;
    type
      TSQLServerDAOImpl=class(Tinterfacedobject,IUserDAO)
        public
          procedure SaveData();stdcall;
      end;
    implementation
    { TSQLServerDAOImpl }
    procedure TSQLServerDAOImpl.SaveData;
    begin
       ShowMessage('TSQLServerDAOImpl');
    end;
    end.
    //实现类2
    unit Unit4;
    interface
    uses
        sysutils, dialogs, classes,  unit2;
    type
      TOracleDAOImpl=class(Tinterfacedobject,IUserDAO)
        public
          procedure SaveData();stdcall;
      end;
    implementation
    { TOracleDAOImpl }
    procedure TOracleDAOImpl.SaveData;
    begin
       ShowMessage('TOracleDAOImpl');
    end;
    end.
    //Client类
      TClientTest=class
        private
          userado:IUserDAO;
        public
          constructor Create(userado:IUserDAO);
          procedure Mytest();
      end;
    constructor TClientTest.Create(userado: IUserDAO);
    begin
       self.userado:=userado;
    end;procedure TClientTest.Mytest;
    begin
       userado.SaveData;
    end;//测试类
    uses
      unit2,unit3;
    procedure TForm1.btn1Click(Sender: TObject);
    var
      JustTest:TClientTest;
      SQLServerDAO:TSQLServerDAOImpl;
    begin
      SQLServerDAO:=TSQLServerDAOImpl.Create;
      JustTest:=TClientTest.Create(SQLServerDAO);
      try
        JustTest.Mytest;
      finally
        //不用释放上述2类,由接口根据引用次数自动释放
      end;
    end;
      

  2.   

    D7没有Namespace或Packge的概念,没法进行类归档,导致unit满天飞~
    写在一个unit中又挺别扭的
      

  3.   

    说点题外话,看楼主的实现代码是运用了策略模式,据我所知,有很多的实现采用的是工厂模式或直接使用Ioc(依赖注入)消除耦合。这种方式就根本不需要再传参数给客户类了。比如:{ 实体抽象基类 }
    TEntity = class
    //...
    end;{ 实体仓库,负责加载和持久化实体对象 }
    IEntityRepository = interface
      function FindOne(const entityID: string): TEntity;
      procedure Insert(entity: TEntity);
      procedure Update(entity: TEntity);
      procedure Delete(entity: TEntity);
      //...
    end;{ 实体仓库注册表 }
    TEntityRepositoryRegistry = class
    //...
    public
      class function GetRepository(entityClass: TClass): IEntityRepository;
      class procedure Register(entityClass: TClass; const repository: IEntityRepository);
      class procedure Unregister(entityClass: TClass);  
    end;
    代码调用方式:
    // 注册代码
    TEntityRepositoryRegistry.Register(TEmployee, TPersonRepository.Create);// 获取代码 { 可将仓库访问代码封装起来,如放在一个全局类,比如TApplicationContext }
    repository := TEntityRepositoryRegistry.GetRepository(TEmployee);补充一下,如果你要封装不同数据库的实现的话,建议采用Query Object来封装查询条件。