2009-01-12 52 views
1

我想标记一个过时的方法,但Delphi 5没有这样的功能。德尔福5:模拟“过时”或“弃用”方法的想法?

举一个例子的缘故,这里是一个虚构的方法与它的过时,新的最佳形式:

procedure TStormPeaksQuest.BlowHodirsHorn; overload; //obsolete 
procedure TStormPeaksQuest.BlowHodirsHorn(UseProtection: Boolean); overload; 

注:对于这个假设的例子中,我们假设使用参数的版本只是很糟糕。有没有“使用保护”的问题 - 这没有很好的解决方案。没有人喜欢使用保护,但没有人想要而不是使用保护。因此,当blowing Hodir's horn时,我们让来电者决定是否要使用保护。如果我们默认的参数的版本使用的保护,继续

procedure TStormPeaksQuest.BlowHodirsHorn; 
begin 
    BlowHodirsHorn(False); //No protection. Bad! 
end; 

那么开发商在各种讨厌的东西的风险。如果我们强制参数的版本使用保护:

procedure TStormPeaksQuest.BlowHodirsHorn; 
begin 
    BlowHodirsHorn(True); //Use protection; crash if there isn't any 
end; 

然后有一个潜在的问题,如果开发商没有得到任何保护,或者不拥有任何。

现在我可以重命名过时的方法:

procedure TStormPeaksQuest.BlowHodirsHorn_Deprecatedd; overload; //obsolete 
procedure TStormPeaksQuest.BlowHodirsHorn(UseProtection: Boolean); overload; 

但是,这会导致编译错误,人们会在我的母狗(我真的不希望听到他们的抱怨)。我希望他们得到唠叨,而不是一个实际的错误。

我想过添加断言:

procedure TStormPeaksQuest.BlowHodirsHorn; //obsolete 
begin 
    Assert(false, 'TStormPeaksQuest.BlowHodirsHorn is deprecated. Use BlowHodirsHorn(Boolean)'); 

    ... 
end; 

但我不能保证开发商不会推出一款版本没有断言,造成讨厌的崩溃为客户

我想过使用仅抛出一个断言,如果开发人员正在调试:

procedure TStormPeaksQuest.BlowHodirsHorn; //obsolete 
begin 
    if DebugHook > 0 then 
     Assert(false, 'TStormPeaksQuest.BlowHodirsHorn is deprecated. Use BlowHodirsHorn(Boolean)'); 

    ... 
end; 

,但我真的不希望在所有导致飞机坠毁。

我想呈现出的MessageDlg的,如果他们是在调试器(这是一个技术,我在过去所做的):

procedure TStormPeaksQuest.BlowHodirsHorn; //obsolete 
begin 
    if DebugHook > 0 then 
     MessageDlg('TStormPeaksQuest.BlowHodirsHorn is deprecated. Use BlowHodirsHorn(Boolean)', mtWarning, [mbOk], 0); 

    ... 
end; 

但仍然过于破坏性。而且它在代码停留在显示模态对话框时造成了问题,但对话框显然不明显。

我一直希望有一种警告信息会在那里唠叨他们 - 直到他们掏出眼睛,最后改变他们的代码。

我想也许如果我加入一个未使用的变量:

procedure TStormPeaksQuest.BlowHodirsHorn; //obsolete 
var 
    ThisMethodIsObsolete: Boolean; 
begin 
    ... 
end; 

我希望这将导致只有当有人引用的代码提示。但是即使你没有实际使用过时的方法,Delphi也会显示提示。

任何人都可以想到别的吗?

+0

嗯。有趣的是,所有提供示例代码的三个答案拼写错了_Hodir_,并且在做这件事时做出了完全相同的错误。 :P – 2011-04-18 22:39:48

+0

我怪我最初的错字,这些人被复制到答案中。我不认为大多数人会得到参考无论如何:) – 2011-04-20 20:18:19

+1

我想你还没有去过诺森德一段时间。 ^^ – 2011-04-20 22:32:56

回答

4

我最终使用的是选择一个系统的组合,您同意没有任何弃用的代码,否则输出调试字符串和断点。

strict html,我创建了Strict define。

如果定义了Strict,则所有常用单位都定义了过时的代码。这样,开发者已经同意,他们将不会在自己的项目中弃用代码:

{$IFNDEF Strict} 
procedure TStormPeaksQuest.BlowHaldirsHorn; overload; //obsolete 
{$ENDIF} 
procedure TStormPeaksQuest.BlowHaldirsHorn(UseProtection: Boolean); {$IFNDEF Strict}overload;{$ENDIF} 


{$IFNDEF Strict} 
procedure TStormPeaksQuest.BlowHaldirsHorn; //obsolete 
begin 
    OutputDebugString(PAnsiChar('TStormPeaksQuest.BlowHaldirsHorn is deprecated. Use BlowHaldirsHorn(Boolean)')); 

    //Don't debugbreak without a debugger attached! 
    if DebugHook > 0 then 
     Windows.DebugBreak; 

    ... 
end; 

因此,如果开发人员希望有正确的代码,苦其时新的东西已被弃用执行代码的变化,他们可以:

{$DEFINE Strict} 

如果不是的话,会有总是是一个OutputDebugString的,和任何人Debug View可以看到(甚至是客户)。看到带有输出调试字符串的商业软件(甚至是微软的)仍然很有趣。最后,如果有一个调试器连接,那么他们将得到一个无处不在的调试断点。如果有人问起,我可以借此机会取笑他们。

0

为什么你想这样做,为什么你不想升级德尔福版本?

没有弃用的标签,你真的没有干净的选择来过滤使用已弃用的方法。所以它取决于你想要让步的地方:

  • 重命名在编译时捕获错误(除非在范围内有另一个同名的方法/函数)。
  • 所有其他方法只在运行时捕获。这有可能滑入生产代码。

你可以做的是创建一个不推荐的日志。这不会让任何人失望,如果它输入了生产代码,它并不是完全的灾难。但是如果你的测试有全面的覆盖,你会抓住所有的罪魁祸首。您只需在(测试)运行后检查日志文件。

当然最好的方法是使用grep来查找代码的所有出现并更改它。

+0

我曾想过添加OutputDebugString(),所以没有人会困扰 - 但没有人会真正看到它。没有眼睛疼痛在这里有一个警告,没有人会修复它 – 2009-01-22 18:33:18

+2

另外我不想升级德尔福版本,因为我不会有几万美元铺设在周围 – 2010-05-14 13:50:35

2

这并不完全回答你的问题,但它可能会提供一个替代解决方案。您是否可以不使用默认值更新原始功能...

procedure TStormPeaksQuest.BlowHaldirsHorn(UseProtection: Boolean = False); 

...因此,遗留代码编译和行为相同,但新功能可供新开发人员使用。

+0

这种方法是最合适的商业产品或当你不想破坏大量现有的代码 – skamradt 2009-01-13 20:15:18

0

我同意一个可选参数,如果它能完成这项工作。但我可以想到情况是可选的参数不适合。例如,我已经将功能移到新单元中,但保留了旧单元并将其标记为已弃用。

我想无论你的解决方案还取决于你的团队的纪律。他们是否积极注意并努力改正其应用程序的所有提示和警告?希望他们能做到,但我很羞于承认与我合作的团队(包括我自己)不会停留在所有提示和警告之上。随着时间的推移,我随时都会修复很多提示,并且我们绝对应该修正警告,但实际上我们必须完成工作,并更关注新功能和最后期限。

所以我的观点是,即使您可以将它们标记为已弃用或给出类似的提示/警告,您是否觉得您的团队会花时间更改其代码?

5

如何像

procedure TStormPeaksQuest.BlowHaldirsHorn; //obsolete 
begin 
    if DebugHook > 0 then asm int 3 end; 
    // This method is Obsolete! Use XXXXX instead. 
    Abort; // Optional, makes method useless 
    // old code here . . . 
end; 

类的断言和showmessage之间的妥协。开发者只需要按F9继续。你可以放置一个Abort,然后这个方法什么也不做,这会迫使他们切换方法,并且break让他们意识到它。

我个人建议升级到更新版本的Delphi。 2007年和2009年是伟大的版本,真的值得升级。

0

这不是一个完整的解决方案,因为您不能区分他们是否使用过该方法,但是如果它在Delphi 5中可用,但是您可以使用$MESSAGE编译器指令在编译时发出警告。

0

没有说“修理我!”像编译器中断一样。
也就是说,我有一个经常修改“通用代码”例程签名的同事...是的,它很烦人!

我的首选(即我们的团队还没有应用:/)的方法如下:

  1. 所有开发人员都必须能够轻松地在自己的机器上执行所有项目的整体构建。
  2. 谁决定改变共同的代码应该承担后果的责任。即修复所有影响的代码。
    • 当然,有时候开发者可能不太适合正确实施和验证所有修补程序。
    • 但是,同样的道理是,开发商在自己的规范中强加“采用新合同”可能并不清楚新合同的细节。即
      • 为了使用保护,有什么特别的事情需要去做吗?
      • 如何实施保护措施?
      • 关于如何破坏现有代码,有哪些担忧?
    • 这是为什么一组全面的测试用例很重要的主要原因。
  3. 一般而言,您希望尽快应用所有更改的连锁效应。即虽然更改的细节在原创开发人员的脑海中是新鲜的 - 在注意转移到别的东西之前!
  4. 涟漪效应如此之大(数千行)以至于您想要在较长的时间内应用此更改应该很少发生。
    • 如果是这种情况,那么实现一个简单的代码度量收集工具集成到您的构建过程中,以报告未完成实例的数量。

我认为第2点是至关重要,这不仅是因为它强调了团队内部的合作和沟通的必要性。

回到我的开场白中,越早抓住并修正错误越好。
让编译器报告一下! - 这是我们拥有的“最早的机会”错误报告机制。

这是我的2铜! :D