这在德尔福看起来如何?

时间:2013-11-13 18:57:16

标签: java delphi delphi-xe4

我的问题与我在上一期("Problems with converting Java code to delphi")中写的那个我仍有问题的问题有关。在我上一个问题中看到的Java代码是我工厂类的一部分,我试图转换为Delphi。问题是我有一个名为IStandardDataProvider的主界面,它包含我工厂中不同类的常用方法。但是由于某些类还包含其他所有方法都不常见的方法。我使用另一个继承自接口IStandardDataProvider的接口。问题是我不能让通用工作吗?在java中看到我的整个工厂类。这在Delphi中会是什么样子?

public class Factory {

    private static HashMap<String, IStandardDataProvider<?>> dataproviders = null;

    @SuppressWarnings("unchecked")
    public <T extends IStandardDataProvider<?>> T GetDataProvider(String dataProviderName) {
        if (dataproviders == null)
            buildDataProviderMap();
        if (dataproviders.containsKey(dataProviderName)) {
            return (T) dataproviders.get(dataProviderName);
        } else
            return null;
    }

    private void buildDataProviderMap() {
        // Build the database connection, that will be used in all the dataproviders
        DatabaseConnectionManager dbConnection = new DatabaseConnectionManager(ConfigurationManager.getConfiguration("sqlConnectionString"));

        // Instantiate the Hashmap 
        dataproviders = new HashMap<String, IStandardDataProvider<?>>();

        // Instantiate all the dataprovider implementations, and put them into the hash map
        dataproviders.put("EventDataProvider", new LocalEventDataProviderImpl(dbConnection));
        dataproviders.put("TaskActivityDataProvider", new LocalTaskActivityDataProviderImpl(dbConnection));
    }
}

更新:好的,这是我的delphi版本,我尝试制作通用版本。目前,我只能访问IStandardDataProvider

type
  TFactory = class(TObject)
  private
    DataProvider: TDictionary<string, IStandardDataProvider >;
    DbConnectionManager : TDatabaseConnectionManager;
    DBConnection : TSQLConnection;
    Configuration : TConfigurationManager;

    procedure BuildDataProviderMap;

  public
    constructor Create;
    destructor Destroy; override;

    function GetDataProvider(DataProviderName: string): IStandardDataProvider;
  end;

implementation

constructor TLocalDataProviderFactory.Create;
begin
  inherited Create;
  DbConnectionManager := TDatabaseConnectionManager.create;
end;

destructor TLocalDataProviderFactory.Destroy;
begin
  inherited;
  DbConnectionManager.Free;
  DataProvider.Free;
end;

function TLocalDataProviderFactory.GetDataProvider(DataProviderName: string): IStandardDataProvider;
begin
  if not Assigned(DataProvider) then
    BuildDataProviderMap;

  if DataProvider.ContainsKey(DataProviderName) then
  begin
    Result := DataProvider.Items[DataProviderName];
  end
  else
  begin
    Result:= nil;
  end;
end;

procedure TLocalDataProviderFactory.BuildDataProviderMap;
begin
  DataProvider := TDictionary<string, IStandardDataProvider>.Create;
  Configuration := TConfigurationManager.Create;
  DBConnection := DbConnectionManager.GetConnection(Configuration.GetConfiguration('sqlConnectionString'));
  DataProvider.Add('EventDataProvider',TLocalEventDataProviderImpl.create(DBConnection) );
  DataProvider.Add('TaskActivityDataProvider',TLocalTaskActivityDataProviderImpl.create(DBConnection) );
end;

end.

1 个答案:

答案 0 :(得分:3)

正如你在other question中被告知的那样,Delphi不支持像Java这样的通配符泛型。你能得到的最接近的是:

type
  IStandardDataProvider<T> = interface(IInterface)
    ...
  end;

type
  TLocalDataProviderFactory = class
  private
    DataProvider: TDictionary<string, IInterface>;
    DbConnectionManager : TDatabaseConnectionManager;
    DBConnection : TSQLConnection;
    Configuration : TConfigurationManager;

    procedure BuildDataProviderMap;

  public
    constructor Create;
    destructor Destroy; override;

    function GetDataProvider<T>(DataProviderName: string): IStandardDataProvider<T>;
  end;

implementation

constructor TLocalDataProviderFactory.Create;
begin
  inherited Create;
  DbConnectionManager := TDatabaseConnectionManager.create;
end;

destructor TLocalDataProviderFactory.Destroy;
begin
  inherited;
  DbConnectionManager.Free;
  DataProvider.Free;
end;

function TLocalDataProviderFactory.GetDataProvider<T>(DataProviderName: string): IStandardDataProvider<T>;
begin
  if not Assigned(DataProvider) then
    BuildDataProviderMap;

  if DataProvider.ContainsKey(DataProviderName) then
    Result := DataProvider.Items[DataProviderName] as IStandardDataProvider<T>
  else
    Result := nil;
end;

procedure TLocalDataProviderFactory.BuildDataProviderMap;
begin
  DataProvider := TDictionary<string, IInterface>.Create;
  Configuration := TConfigurationManager.Create;
  DBConnection := DbConnectionManager.GetConnection(Configuration.GetConfiguration('sqlConnectionString'));
  DataProvider.Add('EventDataProvider', TLocalEventDataProviderImpl.Create(DBConnection) as IInterface);
  DataProvider.Add('TaskActivityDataProvider', TLocalTaskActivityDataProviderImpl.Create(DBConnection) as IInterface);
end;

end.

这对你没有帮助,因为你需要知道实现IStandardDataProvider<T>的具体类才能调用GetDataProvider(),例如:

var
  Provider: IStandardDataProvider<TUpdateTest>;

Provider := Factory.GetDataProvider<TUpdateTest>('EventDataProvider');

否则,忘记尝试让Factory本身支持Generics,让调用代码处理它,例如:

type
  IStandardDataProvider<T> = interface(IInterface)
    ...
  end;

  IEventDataProvider = interface(IStandardDataProvider <TUpdateTest>)
    ...
  end;

type
  TLocalDataProviderFactory = class
  private
    DataProvider: TDictionary<string, IInterface>;
    DbConnectionManager : TDatabaseConnectionManager;
    DBConnection : TSQLConnection;
    Configuration : TConfigurationManager;

    procedure BuildDataProviderMap;

  public
    constructor Create;
    destructor Destroy; override;

    function GetDataProvider(DataProviderName: string): IInterface;
  end;

implementation

constructor TLocalDataProviderFactory.Create;
begin
  inherited Create;
  DbConnectionManager := TDatabaseConnectionManager.create;
end;

destructor TLocalDataProviderFactory.Destroy;
begin
  inherited;
  DbConnectionManager.Free;
  DataProvider.Free;
end;

function TLocalDataProviderFactory.GetDataProvider(DataProviderName: string): IInterface;
begin
  if not Assigned(DataProvider) then
    BuildDataProviderMap;

  if DataProvider.ContainsKey(DataProviderName) then
    Result := DataProvider.Items[DataProviderName]
  else
    Result := nil;
end;

procedure TLocalDataProviderFactory.BuildDataProviderMap;
begin
  DataProvider := TDictionary<string, IInterface>.Create;
  Configuration := TConfigurationManager.Create;
  DBConnection := DbConnectionManager.GetConnection(Configuration.GetConfiguration('sqlConnectionString'));
  DataProvider.Add('EventDataProvider', TLocalEventDataProviderImpl.Create(DBConnection) as IInterface);
  DataProvider.Add('TaskActivityDataProvider', TLocalTaskActivityDataProviderImpl.Create(DBConnection) as IInterface);
end;

end.

var
  Provider: IEventDataProvider;

Provider := Factory.GetDataProvider('EventDataProvider') as IEventDataProvider;