我有多个集合,如:
TFooList = TObjectDictionary<string,TFoo>;
TBarList = TObjectDictionary<string,TBar>;
....
TRoot = class
value : string
end;
TFoo = class(TRoot)
...
end;
TBar = class(TRoot)
...
end;
我有一个可以保存或加载集合的接口/类:
ISave = interface
procedure Save( TDictionary<string, string> );
function Load: TDictionary<string, string>;
end;
请注意,界面需要键/字符串对集合才能正常工作。
我实现了一些ISave类,以便将集合加载到文件或数据库中/从文件或数据库中保存:
TDbSave = class( TInterfacedObject , ISave )
....
end;
iSave := TDbSave( ConnString )
TFileSave = class( TInterfacedObject , ISave )
....
end;
iSave := TFileSave( fileName );
因此,最后一部分将从每个集合继承并创建保存/加载方法,以便&#34;翻译&#34;每个集合进入/来自TDictionary(字符串,字符串)
TFooListSavable = TFooList;
procedure Create( save_load : ISave );
procedure Save;
procedure Load;
....
end;
procedure TFooListSavable.Save
// 1. create a TDictionary<string, string>
// 2. load the dictionary above with my collection translating
// each Foo object into a string
// 3. call save_load.Save( dictionary );
end;
procedure TFooListSavable.Load
// 1. create a TDictionary<string, string>
// 2. call save_load.load to load it
// 3. Move over the collection and translate string into TFoo and
// 4. AddOrEquals each TFoo created into TFooListSavable.
end;
所以,我对这种方法有两个问题:
1)保存或加载的接口需要Collection中的字符串值,虽然每个集合中的所有对象都继承自定义了此字符串的类,但我不知道如何转换集合之类的TDictionary<string,TFoo>
TDictionary<string,string>
不使用上面的代码(将复制集合以将其传递给iSave
对象)。
2)我觉得,虽然我可以替换iSave
个对象来改变保存/加载集合的方式而不改变集合本身,但我不知道这是否是保存的最佳方法/ load集合保留相关对象。
答案 0 :(得分:2)
我认为你这样做是错误的。
ISave
根本不应该有任何TDictionary
的概念。它应该只公开读/写基本数据类型(整数,字符串等)的方法。让TFooListSavable
和TBarListSavable
决定如何序列化他们想要的TDictionary
数据,并根据需要调用ISave
方法。
如果TFooListSavable
和TBarListSavable
将ISave
传递给每个人TFoo
/ TBar
,并让他们直接序列化自己的数据成员,那就更好了。< / p>
例如,像这样:
type
ISerialize = interface
function HasData: Boolean;
procedure StartWriteCollection;
procedure StartWriteItem;
procedure FinishWriteCollection;
procedure FInishWriteItem;
procedure WriteBoolean(value: Boolean);
procedure WriteInteger(value: Integer);
procedure WriteString(const value: String);
...
procedure StartReadCollection;
procedure StartReadItem;
procedure FinishReadCollection;
procedure FinishReadItem;
function ReadBoolean: Boolean;
function ReadInteger: Integer;
function ReadString: String;
...
end;
TRoot = class
public
value : string;
constructor Create; virtual;
procedure Save(Dest: ISerialize); virtual;
procedure Load(Src: ISerialize); virtual;
end;
TBaseList<T: TRoot, constructor> = class(TObjectDictionary<string, T>)
public
procedure Save(Dest: ISerialize);
procedure Load(Src: ISerialize);
end;
TFoo = class(TRoot)
public
myint: Integer;
...
procedure Save(Dest: ISerialize); override;
procedure Load(Src: ISerialize); override;
end;
TFooList = TBaseList<TFoo>;
TBar = class(TRoot)
mybool: Boolean;
...
procedure Save(Dest: ISerialize); override;
procedure Load(Src: ISerialize); override;
end;
TBarList = TBaseList<TBar>;
TDbSerialize = class(TInterfacedObject, ISerialize)
...
end;
TFileSerialize = class(TInterfacedObject, ISerialize)
...
end;
procedure TBaseList<T>.Save(Dest: ISerialize);
var
pair: TPair<string, T>;
begin
Dest.StartWriteCollection;
for pair in Self do
begin
Dest.StartWriteItem;
Dest.WriteString(pair.Key);
TRoot(pair.Value).Save(Dest);
Dest.FinishWriteItem;
end;
Dest.FinishWriteCollection;
end;
procedure TBaseList<T>.Load(Src: ISerialize);
var
Cnt, I: Integer;
key: string;
value: T;
begin
Self.Clear;
Src.StartReadCollection;
While Src.HasData do
begin
Src.StartReadItem;
key := Src.ReadString;
value := T.Create;
try
value.Load(Src);
Self.Add(key, value);
except
value.Free;
raise;
end;
Src.FinishReadItem;
end;
Src.FinishReadCollection;
end;
procedure TRoot.Save(Dest: ISerialize);
begin
Dest.WriteString(value);
end;
procedure TRoot.Load(Src: ISerialize);
begin
value := Src.ReadString;
end;
procedure TFoo.Save(Dest: ISerialize);
begin
inherited;
Dest.WriteInteger(myint);
end;
procedure TFoo.Load(Src: ISerialize);
begin
inherited;
myint := Src.ReadInteger;
end;
procedure TBar.Save(Dest: ISerialize);
begin
inherited;
Dest.WriteBoolean(mybool);
end;
procedure TBar.Load(Src: ISerialize);
begin
inherited;
mybool := Src.ReadBoolean;
end;