Delphi 5: Идеи для моделирования "устаревших" или "устаревших" методов? - PullRequest
1 голос
/ 12 января 2009

Я хочу пометить метод как устаревший, но в Delphi 5 такой функции нет.

В качестве примера, вот метод выдумки с его устаревшей и новой предпочтительной формой:

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

Примечание: Для этого гипотетического примера мы предполагаем, что использование версии без параметров просто плохо. Есть проблемы с " использованием защиты ", которые не имеют хорошего решения. Никто не любит использовать защиту, но никто не хочет не использовать защиту. Поэтому мы заставляем звонящих решать, хотят ли они использовать защиту или нет, когда дует в рог Ходира . Если по умолчанию версия без параметров продолжится , а не с использованием защиты:

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 показывает подсказку, даже если вы не вызываете, на самом деле используйте устаревший метод.

Кто-нибудь может думать о чем-то еще?

Ответы [ 7 ]

5 голосов
/ 13 января 2009

Как насчет чего-то вроде

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 годы - отличные релизы, и они действительно стоят обновления.

4 голосов
/ 29 января 2010

В итоге я использовал комбинацию выбора системы, в которой вы соглашаетесь не использовать устаревший код, в противном случае выведите выходные строки отладки и точки останова.

Как и 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 может видеть (даже клиенты). Забавно видеть коммерческое программное обеспечение (даже Microsoft) с оставленными строками отладки.

И, наконец, если подключен отладчик, они получат точку останова отладки из ниоткуда. Если кто-нибудь спросит, я могу воспользоваться этой возможностью, чтобы посмеяться над ними.

2 голосов
/ 13 января 2009

Это не совсем отвечает на ваш вопрос, но может предложить альтернативное решение. Не могли бы вы обновить исходную функцию со значением по умолчанию ...

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

... так что унаследованный код компилируется и ведет себя так же, но новые функциональные возможности доступны для новых разработчиков.

0 голосов
/ 19 апреля 2011

Ничто не говорит "Исправь меня!" как разрыв компилятора.
Тем не менее, у меня есть коллега, который регулярно модифицирует подписи подпрограмм «общего кода» ... и да, это раздражает!

Мой предпочтительный (т. Е. Наша команда еще не совсем там: /) подход выглядит следующим образом:

  1. Все разработчики должны иметь возможность легко выполнить полную сборку всех проектов на своих компьютерах.
  2. Тот, кто решит изменить общий код, должен нести ответственность за последствия. То есть Исправить весь затронутый код.
    • Конечно, иногда говорят, что разработчик может не идеально подходить для правильной реализации и проверки всех исправлений.
    • Но, к тому же, разработчики, навязанные «принять новый контракт» в своем собственном коде, могут не понимать тонкостей нового контракта. То есть
      • Что-нибудь особенное, что нужно сделать, чтобы использовать защиту?
      • Как реализовано использование защиты?
      • Каковы проблемы относительно того, как это может сломать существующий код?
    • Это основная причина, по которой важен комплексный набор тестовых случаев.
  3. Как правило, вы хотите, чтобы эффект пульсации всех изменений был применен как можно скорее. То есть В то время как более тонкие детали изменения свежи в голове у зарождающегося разработчика, прежде чем внимание переключится на что-то другое!
  4. Должно быть редким явлением, что волновой эффект настолько велик (тысячи строк), что вы хотите применить изменение в течение длительного периода времени.
    • Если это так, то внедрите простой инструмент сбора метрик кода, интегрированный в процесс сборки, чтобы сообщить о количестве ожидающих экземпляров.

Я считаю, что пункт 2 имеет ключевое значение, не в последнюю очередь потому, что в нем подчеркивается необходимость сотрудничества и общения внутри команды.

Возвращаясь к моему вступительному заявлению, чем раньше вы поймаете и исправите ошибку, тем лучше.
Позвольте компилятору сообщить об остановке! - Это самый ранний из имеющихся у нас механизм сообщения об ошибках.

Это мои 2 котла! : D

0 голосов
/ 30 января 2010

Это не полное решение, так как вы не можете различить, использовали ли они метод или нет, но если он доступен в Delphi 5, но вы можете использовать директиву компилятора $ MESSAGE , чтобы выдавать предупреждение при время компиляции.

0 голосов
/ 13 января 2009

Я бы согласился с дополнительным параметром, если он справится с работой. Но я могу думать о ситуациях, когда необязательные параметры не подходят. Например, я переместил функции в новые модули, но сохранил старые и отметил их как устаревшие.

Я думаю, какое бы решение вы ни выбрали, оно также будет зависеть от дисциплины вашей команды. Они активно обращают внимание и стараются исправить все подсказки и предупреждения для своих приложений? Надеюсь, что они это сделают, но мне стыдно признать, что команда, с которой я работаю (включая меня), не остается в курсе всех намеков и предупреждений. Время от времени я исправляю столько подсказок и предупреждений, сколько позволяет время, и мы обязательно должны исправлять предупреждения, но в действительности мы должны выполнить свою работу и сосредоточиться на новых функциях и сроках.

Таким образом, моя точка зрения такова, что даже если вы могли бы пометить их как устаревшие или дать аналогичную подсказку / предупреждение, считаете ли вы, что ваша команда все равно потратит время на изменение своего кода?

0 голосов
/ 13 января 2009

Почему вы хотите это сделать и почему вы не хотите обновить версию Delphi?

Без устаревшего тега у вас действительно нет чистой опции для фильтрации использования устаревших методов. Так что это зависит от того, где вы хотите пойти на уступку:

  • переименование перехватывает ошибку во время компиляции (если в области действия нет другого метода / функции с тем же именем).
  • все остальные методы перехватываются только во время выполнения. И это может поскользнуться в рабочем коде.

Что вы можете сделать, так это создать устаревший журнал. Это никого не разозлит, и это не будет полной катастрофой, если он войдет в производственный код. Но если ваши тесты имеют полное покрытие, вы поймали всех виновных. Вы должны проверить файл журнала только после (тестового) запуска.

И, конечно же, лучший способ - использовать grep, чтобы найти все вхождения кода и изменить его.

...