7

我正在尝试定义重构我正在从事的项目的最佳方式。

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

1) 包含业务逻辑的表单

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

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

没有OOP(除了一些小领域),代码重用它处于最低水平。

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

理想情况下,我想提取诸如 TCustomer、TEmployee 之类的类,以获得优势 os 封装,并使将来可以在不复制所有代码的情况下创建新的 UI。

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

function TCustomer.LoadByID(aCustomerID: integer): TDataset

?

4

2 回答 2

9

你被绑定到你的应用程序设计的架构。不要试图与之抗争。让数据感知控件做他们擅长的事情,即数据同步。如果您的控件已经使用 dfm 绑定到其数据源,则应该没有问题。

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

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

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

IProductView = interface
end;

然后让你的表单实现它。

TProductForm = class(TForm, IProductView)
...
end;

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

TProductPresenter = class
private
  FView: IProductView;
public
  constructor Create(AView:IProductView);
end;

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

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

implementation
TProductForm.Create
begin
  FPresenter := TProductPresenter.Create(self);
end;

现在,当您需要表单或其控件之一来响应事件时,将责任委托给演示者。假设您需要检查产品名称是否使用了正确的大小写。

TProductForm.NameDBEditChange(Sender: TObject);
begin
  FPresenter.ValidateName;
end;

与其将控件或其文本属性作为参数传递,不如将数据作为接口上的属性公开......

IProductView = interface
  function GetName:string;
  procedure SetName(Value: string);
  property Name: string read GetName write SetName;

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

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

TProductForm.SetName(Value: string);
begin
  NameDBEdit.Text := Value;
end;

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

现在您的所有业务逻辑都已移至您的演示者,它将类似于一个上帝类。您的下一步将是将该逻辑重构为按职责分解的适当类。当您达到这一点时,您将处于一个更好的位置来尝试重新设计架构(如果您仍在考虑它)。

“哇!看起来工作量很大!” 你可能会说。你是对的(但你知道在开始之前会做很多工作)。它不必一次完成。这些步骤都没有改变逻辑发生的地方的行为。

好处

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

缺点

  • 一开始需要做更多的工作,尽管这最终会被更多可维护的代码所抵消。
  • 不适合所有应用。对于小型项目,额外的基础设施可能不值得付出努力。

其他参考

于 2010-10-29T15:46:46.017 回答
1

如果代码中没有好的设计并且没有真正的 OOP,那么考虑到它的复杂性,您应该首先创建一个描述其当前功能的设计。是的,这意味着您一开始会忙于编写大量文档。但它允许您将整个项目拆分为逻辑/功能部分,一旦完成此文档,您就可以使用这些部分专注于这些部分。然后,您可以分别重构每个部分,甚至可能重写这些部分。
如此复杂的项目并不总是适合重构。您应该返回原始设计(因此创建它,因为您没有),然后查看您的代码并考虑更快的方法:重构或重写......

于 2010-10-29T13:11:23.510 回答