【发布时间】:2014-02-16 10:44:24
【问题描述】:
我正在为我的所有应用程序模块使用某种(类似于 MVA)的模式。
视图是TForm后代:
TSomeView = class(TForm)
...
end;
数据在模型中管理:
TSomeModel = class
public
property DataSet: TDataSet read ...;
end;
视图和模型通过适配器粘合在一起。
uses
Some.Model, Some.View;
type
TSomeAdapter = class
private
FView : TSomeView;
FModel : TSomeModel;
procedure ClickHandler(Sender: TObject);
public
constructor Create(AOwner: TComponent);
destructor Destroy; override;
procedure Run;
end;
虽然这看起来有点乏味,但它可以很好地分隔事物。
到目前为止,我一直使用模态形式,因此适配器实现如下所示:
constructor TSomeAdapter.Create(AOwner: TComponent);
begin
inherited Create;
FModel := TSomeModel.Create,
FView := TSomeView.Create(AOwner);
FView.DataSource.DataSet := FModel.DataSet;
FView.SomeButton.OnClick := ClickHandler;
end;
procedure TSomeAdapter.Run;
begin
FView.ShowModal;
end;
destructor TSomeAdapter.Destroy;
begin
FView.Free;
FModel.Free;
inherited;
end;
这里重要的是我不会在析构函数中断开事件处理程序和数据集,因为视图总是首先被销毁。
调用者使用这种模式创建一个应用模块:
procedure CallSome;
var
Adapter: TSomeAdapter;
begin
Adapter := TSomeAdapter.Create(...);
try
Adapter.Run;
finally
Adapter.Free;
end;
end;
我正在尝试使其适应非模态形式。
调用者无法释放适配器,因为它不知道何时。所以调用者代码现在看起来像这样:
procedure CallSome;
var
Adapter: TSomeAdapter;
begin
Adapter := TSomeAdapter.Create(...);
Adapter.Run;
// Adapter is now a memory leak
end;
我不想更改销毁顺序,因为我依赖于不需要断开处理程序和数据集的事实。
使用非模态表单时如何保持销毁顺序(视图
【问题讨论】:
-
在您的模态方法中,您只有一个视图 -> 一个适配器。现在您有多个适配器。在列表中组织多个元素
-
不仅如此,您可能无法再直接在 callsome 中创建适配器,可能已经有一个正在运行。看起来会变得更加乏味...
-
您可能需要考虑以下几点:a) 将
TSomeAdapter更改为更通用的类,该类将注入TSomeView和TSomeModel,因此它之前不需要知道它们。这意味着两者都需要从抽象类派生或实现接口。 b)考虑也注入它们已经创建,但如果构造函数并不总是相同的,这可能是一个问题。 c) 创建一个类,该类包含对创建的所有TSomeAdapter的引用。 d) 使TSomeAdapter完成后通知持有者类,以便释放它。 -
我不担心阻塞多个实例。该应用程序有一个主模块,我可以使用它来保存所有适配器的列表。
-
@GuillemVicens 好主意,关于通知:也许我可以在主窗口中使用
PostMessage?
标签: delphi model-view-controller delphi-xe3 object-lifetime