关于重构一些糟糕代码的建议

时间:2013-04-16 17:53:52

标签: delphi refactoring delphi-5

考虑以下

constructor TSettlement.Assign( const OldInst : TSettlement; const ResetFsToo: Boolean );
begin
  //inherited
  Create;
  if OldInst = nil then
    exit;

  Self.Acceptancedate := OldInst.Acceptancedate;
  // etc etc
end;

请在代码的其他地方考虑这些调用

SettInst.Assign(DisplaySett, False);

DisplaySett := TSettlement.Assign(nil, False);

NewInst := TSettlement.Assign( Displaysett, False );

和(也许最糟糕的)

  if OldList.Count > 0 then
    for loop := 0 to OldList.Count -1 do  
      Self.Add(TSettlement.Assign(OldList.Data[loop], True));

这是漏洞代码,我反对使用方法名称“Assign”作为构造函数,原因我明白,但我 不得不修复它。

我想改进它,因为我为自己的工作感到自豪。

我建议将Assign方法从构造函数更改为过程,并删除对Create()的调用。这将要求我在应用程序的许多地方更改代码。显然这样做有风险。

在我潜入并开始破解之前,任何人都可以建议我应该考虑采用其他方法吗?

我是否可能没有想到我应该注意的陷阱?

1 个答案:

答案 0 :(得分:4)

该构造函数不一定泄漏。代码实际上是有效的,这似乎是合理的。然而,它是无法穿透的并且导致调用其语义难以从外部辨别的代码。你应该重构。

有一种简单的重构方法。关键是你将两种操作模式分解为单独的函数:

  1. 一个名为Create的构造函数,其作用类似于普通的Delphi构造函数。你似乎已经有了这个。
  2. 将一个实例的内容复制到另一个实例的过程。这可以命名为Assign。
  3. 所以,这是竞选计划:

    1. 将分配更改为过程而不是构造函数。
    2. 处理可在当前Assign中找到的Create的调用。您需要从Assign中删除它,但确保在分配运行时它仍然发生的一切。
    3. 现在所有构造函数模式调用Assign都无法编译。所以我们修复它们。
    4. 传递nil的那些,转换为Create的构造函数调用。
    5. 其他人需要调用Create构造函数,然后调用Assign。
    6. 您可能希望重载的Create接收现有实例并调用Assign。这可能很方便。

      这会让你能够完成你今天所做的一切,但是会避免在实例上调用构造函数,这总是一个坏主意。