Изящный рефакторинг перечисляемых типов

Posted by on in Blogs

Столкнулся с проблемой. Кода много, много перечисляемых типов, объявленных примерно так:

type
TMyType = (mtOne, mtTwo, mtThree, mtFour, mtFive);


Это было удобно в старых версиях Дельфи, когда мы присваивали значения, без указания типа. Т.е.

var
LVariable : TMyType;
...
begin
LVariable := mtThree;

 



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

  LVariable := TMyType.mtThree;


Как убрать префикс наиболее безболезненно? Разумеется, можно создать рядом новый тип, пометить старый как Deprecated, нагородить кучу методов и перелопатить много кода, поскольку нужна совместимость со старым кодом.
Есть решение проще и это решение предложено Алленом Бауэром - использовать хелперы.

type
TMyType = (One, Two, Three, Four, Five);

TMyTypeHelper = record helper for TMyType
const
mtOne = TMyType.One deprecated 'Use TMyType.One';
mtTwo = TMyType.Two deprecated 'Use TMyType.Two';
mtThree = TMyType.Three deprecated 'Use TMyType.Three';
mtFour = TMyType.Four deprecated 'Use TMyType.Four';
mtFive = TMyType.Five deprecated 'Use TMyType.Five';
end;


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

 
[dcc32 Warning] Unit41.pas(47): W1000 Symbol 'eThree' is deprecated: 'Use TMyType.Three'
Tags: RUS


Comments

  • Guest
    Sergey Pyankov Sunday, 24 November 2013

    А почему не использовать инструмент для рефакторинга, встроенный в IDE: Refactor -> Rename?

  • Guest
    nikolay Sunday, 24 November 2013

    Безусловно, это тоже вариант.

    Но иногда мы не можем переименовать всё.
    Допустим мы выпускаем свой компонент. Объявили свой перечислимый тип. Наши пользователи на него завязались, написали свой код.
    Допустим у нас возникла необходимость переименования значений перечислимого типа. Мы прибегли к описанному Вами рефакторингу. Ну а далее, используя этот метод, мы написали хелпер и в результате мы сохраняем рабочий код на стороне пользователя и уведомляем его, что старые имена устарели.

  • Guest
    Alexandr Androschuk Monday, 25 November 2013

    Просто и со вкусом. Спасибо за статью.

  • Guest
    Alex W. Lulin Tuesday, 26 November 2013

    Непонятно только - зачем понадобился helper. Почему просто определение констант не подошло?

  • Guest
    Terekhov Andrey Tuesday, 26 November 2013

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

    одно дело то что в недрах FMX включены {$SCOPEDENUMS} а другое - ваш код. хотите использовать - используйте, не хотите, пишите как как писали раньше.

  • Guest
    nikolay Tuesday, 26 November 2013

    Основная задача - рефакторинг. А именно - наиболее безболезненное переименование перечисляемых типов.
    Если раньше было
    type
    TMyType = (mtOne, mtTwo, mtThree, mtFour, mtFive);
    И использовалось это всюду как
    LVariable := TMyType.mtThree;
    Т.е. кроме указания перечисляемого типа, мы добавляли к значению префикс. То сейчас задача убрать префикс, сохранив работоспособность кода в том числе и для сторонних разработчиков, использующих эти типы.
    Таким образом, сторонний разработчик, использующий этот тип, может использовать как
    LVariable := TMyType.Three;
    так и
    LVariable := TMyType.mtThree;
    Только во втором случае мы дополнительно сообщаем ему, что использование варианта с префиксом устарело и следует использовать вариант без префикса.

  • Guest
    Alex W. Lulin Tuesday, 26 November 2013

    "так и
    LVariable := TMyType.mtThree;
    Только во втором случае мы дополнительно сообщаем ему, что использование варианта с префиксом устарело и следует использовать вариант без префикса."

    По моему для целей именно рефакторинга это - совсем лишнее.

  • Guest
    Terekhov Andrey Wednesday, 27 November 2013

    ну это все понятно,
    просто вы пишете:
    "Времена поменялись, теперь указываем тип и в префиксах необходимость отпала." (с)

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

    кстати да, для именно рефакторинга это лишнее. а вот для поддержания обратной совместимости на некоторое время при переходе к использованию {$SCOPEDENUMS ON} [а зачем вобще? :)] вариант очень хороший.

  • Guest
    Alex W. Lulin Thursday, 28 November 2013

    "как будто это теперь единственный путь, и работать без указания типа нельзя. Но по факту это как было так и остается чисто на ваше усмотрение.

    кстати да, для именно рефакторинга это лишнее. а вот для поддержания обратной совместимости на некоторое время при переходе к использованию {$SCOPEDENUMS ON} [а зачем вобще? :)] вариант очень хороший."

    ПЯТЬ БАЛЛОВ!!! БРАВО Андрей. СОЛИДАРЕН с Вами.

  • Guest
    Michaelmuck Wednesday, 14 May 2014

    Я считаю, что Вас ввели в заблуждение.

    http://www.yeiskomp.ru/" rel="nofollow">слушать транс

  • Please login first in order for you to submit comments
  • Page :
  • 1

Check out more tips and tricks in this development video: