我的问题与我在上一期("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.
答案 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;