Каковы лучшие практики для постепенного отказа от устаревшего кода?

9

У меня есть необходимость отказаться от устаревшего метода. Я знаю об [Obsolete]атрибуте. Есть ли у Microsoft рекомендуемое руководство для этого?

Вот мой текущий план:

О. Я не хочу создавать новую сборку, потому что разработчики должны будут добавить новую ссылку на свои проекты, и я ожидаю получить много горя от моего начальника и коллег, если они должны сделать это. Мы также не поддерживаем несколько версий сборки. Мы используем только последнюю версию. Изменение этой практики потребует изменения нашего процесса развертывания, что является большой проблемой (нужно научить людей, как делать вещи с TFS вместо FinalBuilder и заставить их отказаться от FinalBuilder)

Б. Отметьте старый метод как устаревший.

C. Поскольку реализация меняется (не сигнатура метода), мне нужно переименовать метод, а не создавать перегрузку. Итак, чтобы пользователи знали о правильном методе, я планирую добавить сообщение к [Obsolete]атрибуту. Эта часть беспокоит меня, потому что единственное изменение, которое я делаю, - это отделение метода от строки подключения. Но, поскольку я не добавляю новую сборку, я не вижу способа обойти это.

Результат:

[Obsolete("Please don't use this anymore because it does not implement IMyDbProvider.  Use XXX instead.")];
        /// <summary>
        /// 
        /// </summary>
        /// <param name="settingName"></param>
        /// <returns></returns>
        public static Dictionary<string, Setting> ReadSettings(string settingName)
        {
            return ReadSettings(settingName, SomeGeneralClass.ConnectionString);
        }

        public Dictionary<string, Setting> ReadSettings2(string settingName)
        {
            return ReadSettings(settingName);// IMyDbProvider.ConnectionString private member added to class.  Probably have to make this an instance method.
        }
P.Brian.Mackey
источник

Ответы:

5

Microsoft использует атрибут [устаревший], чтобы сообщить разработчикам, что метод, свойство или класс устарели и могут быть изменены (или вообще не поддерживаться) в будущих выпусках.

Это дает вам по крайней мере один цикл выпуска, чтобы уведомить пользователей вашего API о том, что их функция «исчезает», и удалить ссылки на него в будущих выпусках их программного обеспечения.

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

Как указывает Брайан, если вы изменяете только базовую реализацию, но не сигнатуру метода, вам, возможно, вообще не нужно ничего делать.

Роберт Харви
источник
Практика Microsoft, как правило, заключается в удалении устаревшей вещи в следующем основном выпуске. В отличие от этого, Java никогда не удаляет устаревшие вещи - так что вам решать.
Скотт С. Уилсон,
Мы не занимаемся сборкой версий за пределами уровня приложения (1 гигантское приложение со многими решениями). Объедините это с тем фактом, что количество решений, зависящих от любой данной сборки, не определено. Я не могу протестировать приложение, о котором я не знаю. Но если я внесу изменение, которое приведет к повреждению приложения, о котором я не знаю ... ну, это моя вина. Вот почему я переименовал метод. Итак, из того, что я прочитал до сих пор, нет лучшего способа сделать это.
P.Brian.Mackey
4

Поскольку реализация меняется (не сигнатура метода), мне нужно переименовать метод, а не создавать перегрузку.

Я не понимаю Если реализация меняется, а подпись - нет, зачем вам это делать? Пусть «старый» метод использует новую и улучшенную реализацию. Любые разработчики, использующие этот API, будут закатывать глаза, когда увидят метод с точно такой же созданной сигнатурой и предупреждения об устаревании в существующих вызовах методов. (Можете ли вы вспомнить время, когда это случалось в API?)

Если вы не уверены, сработает ли базовая реализация этого метода, проверьте поведение с помощью модульных тестов до и после изменения реализации.

Брайан
источник
Это хороший идеал. Проблема в том, что у нас нет проводов для тестирования. Это еще одна проблема, которую я надеюсь решить. Поэтому, поскольку нет интеграционного тестирования, я не могу делать то, что вы рекомендуете. Слишком много неопределенных зависимостей, которые не будут проверены.
P.Brian.Mackey
Причина, по которой я упомянул тестирование, заключается в том, что вы явно хотели сделать это, чтобы те, кто использует ваш API, провели тестирование и помогли вам выяснить любые проблемы между двумя вызовами. Ваш лучший вариант - бросить в огонь разработчиков, использующих ваш код, и заставить их использовать новую реализацию и надеяться, что они проведут тщательный контроль качества или проведут собственные тесты.
Брайан,
Я бы бросился в огонь. Я бы предпочел придерживаться исходного кода, который я разместил. Таким образом, никто не звонит мне в 3 часа ночи, спрашивая, почему сломался производственный код. Затем зависите от разработчиков, которые решают проблему устаревания кода по мере прохождения и исправления своих предупреждений. Если они не исправят это в тот момент, то, когда строки подключения начинают выходить из строя на них, это их вина, что они не восстановили свои предупреждающие флаги ... не мои.
P.Brian.Mackey
Всякий раз, когда вы пишете новый код, вы рискуете вызвать проблемы. Тесты позволят вам проводить рефакторинг, не боясь так сильно. Страх убивает мысль. Плюс вы просто откладываете неизбежное; они неохотно добавят «2» к своему звонку через пару итераций, и вы получите тот же телефонный звонок, если он не сработает.
Брайан,