我对Delphi和Delphi中的接口没有太多经验。防止通过接口传递对象的破坏
实施例:
IListModel = interface
function At(row, col : Integer) : String;
end;
MyModel = class(TInterfacedObject, IListModel)
public
function At(row, col : Integer) : String;
procedure ManipulateA;
procedure ManipulateBogus;
end;
没有可以可视化实现IListModel接口的对象的视图。
View = class(TForm)
public
constructor Create(model : IListModel); reintroduce;
end;
我的应用程序拥有为MyModel实例
MyApp = class({...})
strict private
model : MyModel;
public
// ...
end;
在应用程序中我创建了模型,并使用它。
procedure MyApp.LoadModel;
procedure MyApp.OnFoo;
begin
model.ManipulateBogus;
end;
现在,我想表明我不知道什么是解决这个问题的最好办法中的数据
procedure MyApp.ShowModel;
var
v : View;
begin
v := View.Create(model); // implicit to IListView > refCount=1
v.ShowModal;
FreeAndNil(v);
// refCount = 0
// oops, my model is dead now
end;
。 在MyApp中,我可以同时拥有实例模型:MyModel和通过IListModel接口。 或者我可以引入一个新的接口IMyModel,并通过MyApp类中的这个接口保存模型。我必须使用ShowModel方法中的Supports(...)来获取IListModel接口。 或者我从另一个非refcounting基类(TInterfacedPersistent或自写的类)派生MyModel类。任何其他想法?
在这种情况下使用接口的最佳方式是什么?
编辑: 非裁判计数的基类:
function NonRefCountingObject.QueryInterface(const IID: TGUID;
out Obj): HResult;
begin
if GetInterface(IID, Obj) then
Result := S_OK
else
Result := E_NOINTERFACE;
end;
function NonRefCountingObject._AddRef: Integer;
begin
Result := -1; // no reference counting
end;
function NonRefCountingObject._Release: Integer;
begin
Result := -1; // no reference counting
end;
这是实现好不好?
Thx为您的答案。用编辑中的NonRefCountingObject类替换TInterfacedObject或TComponent基类是否安全?这个实现是否正确? – hansmaad 2010-11-12 08:35:00
是的,正确的 – 2010-11-12 11:05:42
@hansmaad:Lars在他的第一句话中的含义是,你应该用'model:IListModel'替换'MyApp'中的'model:MyModel'。这确保'MyApp'保持一个引用(直到'MyApp'死亡;然后'model'的refcount减少,当refcount变为零时,它被自动释放)。 – 2010-11-12 12:07:45