Delphi重构示例,涉及数据感知控件和可直接访问db表的数据模块

LaB*_*cca 7 delphi refactoring data-aware datamodule

我正在尝试定义重构我正在进行的项目的最佳方法.

由于缺乏良好的设计,几乎所有项目都由以下部分组成:

1)包含业务逻辑的表单

2)巨大的数据模块(每个表单1个+额外的一些)

3)包含公共代码(库)的一些单元

没有OOP(除了一些小区域),代码重用它是最低级别的.

一个问题是使用了数据感知控件,因此在数据模块上删除许多数据集+数据源并以高度耦合的方式直接链接到数据库非常简单.

理想情况下,我想提取类,如TCustomer,TEmployee,以获得os封装的优势,并且可以在将来创建新的UI而无需复制所有代码.

无论如何,我的问题是:如何继续处理数据控件?我应该实现一个返回数据集的函数,并将dataawarecomponent.datasource链接到函数结果吗?

function TCustomer.LoadByID(aCustomerID: integer): TDataset
Run Code Online (Sandbox Code Playgroud)

Ken*_*ran 9

您将受到应用程序设计的体系结构的约束.不要试图反对它.让数据感知控件做他们擅长的事情,数据同步.如果您的控件已使用dfm绑定到其数据源,则应该没有问题.

您需要重构的是您附加到控件的任何事件处理程序.我建议你看看监督控制器模式.我找到了以下示例实现:

虽然在Delphi中有一些UI架构模式的例子,那些面向桌面应用程序的例子往往是被动视图而不是监督控制器.所以这是我的看法.

您将首先为应用程序中的每个表单定义至少一个接口.我说至少有一个因为某些形式很复杂,可能需要分解成多个接口.

IProductView = interface
end;
Run Code Online (Sandbox Code Playgroud)

然后让你的表单实现它.

TProductForm = class(TForm, IProductView)
...
end;
Run Code Online (Sandbox Code Playgroud)

接下来你需要一个演示者/控制器.这将处理除数据同步之外的所有内容

TProductPresenter = class
private
  FView: IProductView;
public
  constructor Create(AView:IProductView);
end;
Run Code Online (Sandbox Code Playgroud)

在表单类中创建一个私有字段,并在创建/释放表单时创建/释放演示者.无论您使用表单的构造函数/析构函数还是onCreate/onDestroy事件都无关紧要.

TProductForm = class(TForm, IProductView)
private
  FPresenter: TProductPresenter;
public
  constructor Create;
...
end;

implementation
TProductForm.Create
begin
  FPresenter := TProductPresenter.Create(self);
end;
Run Code Online (Sandbox Code Playgroud)

现在,当您需要表单或其中一个控件来响应事件委托给演示者的责任时.让我们假设您需要检查产品名称是否使用了适当的大小写.

TProductForm.NameDBEditChange(Sender: TObject);
begin
  FPresenter.ValidateName;
end;
Run Code Online (Sandbox Code Playgroud)

而不是将控件或其text属性作为参数传递,而是将数据公开为接口上的属性...

IProductView = interface
  function GetName:string;
  procedure SetName(Value: string);
  property Name: string read GetName write SetName;
Run Code Online (Sandbox Code Playgroud)

...和实施GetName,并SetName在表格上.

TProductForm.GetName: string;
begin
  Result := NameDBEdit.Text;
end;

TProductForm.SetName(Value: string);
begin
  NameDBEdit.Text := Value;
end;
Run Code Online (Sandbox Code Playgroud)

以最简单的形式公开数据非常重要.您不希望演示者取决于存储在TDBEdit中的产品名称.演示者应该只看到您明确允许它通过界面查看的内容.这样做的主要好处是您可以根据需要修改表单(或完全替换它),只要它符合界面,就不需要对演示者进行任何更改.

现在您的所有业务逻辑都已移至您的演示者,它将类似于神级.您的下一步将是将该逻辑重构为由责任分解的适当类.当你达到这一点时,你可以更好地尝试进行架构重新设计(如果你还在考虑它).

"哇!看起来很多工作!" 你可能会说.你是对的(但是在你开始之前你知道这将是很多工作).它不必一次完成.这些步骤都没有改变逻辑行为的位置.

好处

  • UI现在很容易修改
  • 业务逻辑可以更容易地单独测试
  • 可以逐步实施

缺点

  • 一开始它的工作量更大,但最终会被更易于维护的代码所抵消.
  • 不适合所有应用.对于小型项目,额外的基础设施可能不值得.

其他参考