我想将方法标记为过时,但Delphi 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;
但这会导致编译错误,人们会嘲笑我(我真的不想听到他们的抱怨)。我希望他们得到 nag ,而不是实际错误。
我想添加一个断言:
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 :(得分: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;
断言与表演之间的妥协。开发人员只需要按F9继续。您可以放入Abort,然后该方法将不执行任何操作,这将迫使他们切换方法,并且中断使他们意识到它。
就个人而言,我建议升级到较新版本的Delphi。 2007年和2009年是很棒的版本,非常值得升级。
答案 1 :(得分:4)
我最终使用的是选择加入系统的组合,其中您同意不使用任何已弃用的代码,否则输出调试字符串和断点。
与strict
html一样,我创建了Strict
定义。
如果定义了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的任何人都可以看到(甚至是客户)。看到带有输出调试字符串的商业软件(甚至微软)很有趣。
最后,如果附加了一个调试器,那么它们将无处获得调试断点。如果有人问起,我可以借此机会取笑他们。
答案 2 :(得分:2)
这并不能完全回答您的问题,但它可能会提供另一种解决方案。你能不能用默认值更新原始功能......
procedure TStormPeaksQuest.BlowHaldirsHorn(UseProtection: Boolean = False);
...因此遗留代码编译和行为相同,但新功能可供新开发人员使用。
答案 3 :(得分:0)
为什么要这样做?为什么不想升级Delphi版本?
如果没有弃用的标记,您实际上没有干净的选项来过滤使用不推荐的方法。所以这取决于你想要让步的地方:
您可以做的是创建一个已弃用的日志。这不会让任何人感到沮丧,如果它输入生产代码,那就不是彻底的灾难。但是如果你的测试有完整的覆盖范围,那么你将会抓住所有的罪魁祸首。您只需在(测试)运行后检查日志文件。
当然最好的方法是使用grep查找代码的所有出现并更改它。
答案 4 :(得分:0)
我同意一个可选参数,如果它能完成这项工作的话。但我可以想到情况是可选的params不适合。例如,我已将函数移动到新单元中,但保留旧单元并将其标记为已弃用。
我猜你使用的解决方案也取决于团队的纪律。他们是否积极注意并努力纠正其应用的所有提示和警告?希望他们这样做,但我很惭愧承认我与之合作的团队(包括我自己)并没有留在所有的提示和警告之上。我时不时地修复了许多提示&警告在时间允许的情况下,我们绝对应该修复警告,但实际上我们必须完成工作,更专注于新功能和截止日期。
所以我的观点是,即使您可以将其标记为已弃用或提供类似的提示/警告,您是否认为您的团队会花时间更改其代码?
答案 5 :(得分:0)
这不是一个完整的解决方案,因为你无法区分他们是否使用过该方法,但是如果它在Delphi 5中可用,但你可以使用$MESSAGE编译器指令在编译时发出警告。
答案 6 :(得分:0)
没有什么能说“修复我!”像编译器休息一样 也就是说,我有一位同事定期修改“常用代码”例程的签名......是的,这很烦人!
我的首选(即我们的团队尚不完全:/)方法如下:
我认为第2点至关重要,尤其是因为它强调了团队内部合作与沟通的必要性。
回到我的开场白,越早抓住并修复错误,就越好 让编译器报告休息! - 这是我们的“最早机会”错误报告机制。
那是我的两个人! :d