Jakie są najlepsze praktyki dotyczące wycofywania przestarzałego kodu?

9

Mam potrzebę wycofania przestarzałej metody. Mam świadomość tego [Obsolete]atrybutu. Czy Microsoft ma zalecany przewodnik najlepszych praktyk w tym zakresie?

Oto mój obecny plan:

A. Nie chcę tworzyć nowego zestawu, ponieważ programiści musieliby dodać nowe odniesienie do swoich projektów i spodziewam się dużo żalu od mojego szefa i współpracowników, jeśli będą musieli to zrobić. Nie utrzymujemy również wielu wersji zestawu. Używamy tylko najnowszej wersji. Zmiana tej praktyki wymagałaby zmiany naszego procesu wdrażania, co jest dużym problemem (trzeba nauczyć ludzi, jak robić rzeczy z TFS zamiast z FinalBuilder i zmusić ich do rezygnacji z FinalBuilder)

B. Oznacz starą metodę jako przestarzałą.

C. Ponieważ implementacja się zmienia (nie podpis metody), muszę zmienić nazwę metody zamiast tworzyć przeciążenie. Aby więc uświadomić użytkownikom właściwą metodę, planuję dodać wiadomość do [Obsolete]atrybutu. Ta część mnie niepokoi, ponieważ jedyną zmianą, którą wprowadzam, jest oddzielenie metody od ciągu połączenia. Ale ponieważ nie dodam nowego zestawu, nie widzę w tym żadnej możliwości.

Wynik:

[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
źródło

Odpowiedzi:

5

Microsoft używa atrybutu [przestarzałe], aby poinformować programistów, że metoda, właściwość lub klasa są przestarzałe i mogą zostać zmienione (lub w ogóle nieobsługiwane) w przyszłych wydaniach.

To daje co najmniej jeden cykl wydania, aby powiadomić użytkowników interfejsu API, że ich funkcja „odchodzi”, i usunąć odniesienia do niej w przyszłych wydaniach ich oprogramowania.

To, jak długo pozostawisz oryginalną funkcję, zależy wyłącznie od Ciebie. Jeśli chcesz „zdecydowanie zachęcić” programistów do korzystania z nowych funkcji w porównaniu ze starymi, potrzebujesz tylko jednego dodatkowego cyklu wydania, aby je usunąć. Jeśli chcesz mieć stałą zgodność wsteczną, możesz pozostawić ją na zawsze.

Jak zauważa Brian, jeśli zmieniasz tylko podstawową implementację, ale nie sygnaturę metody, być może nie musisz wcale tego robić.

Robert Harvey
źródło
Praktyka Microsoftu polega zazwyczaj na usuwaniu przestarzałej rzeczy w następnej głównej wersji. Z kolei Java nigdy nie usuwa przestarzałych rzeczy - więc to zależy od Ciebie.
Scott C Wilson,
Nie wykonujemy wersji zespołów poza poziomem aplikacji (1 gigantyczna aplikacja z wieloma rozwiązaniami). Połącz to z faktem, że liczba rozwiązań zależnych od dowolnego zestawu jest niezdefiniowana. Nie mogę przetestować aplikacji, o której nie wiem. Ale jeśli dokonam zmiany, która spowoduje uszkodzenie aplikacji, o której nie wiem ... cóż, to moja wina. Właśnie dlatego zmieniłem nazwę metody. Tak więc, z tego, co przeczytałem do tej pory, nie ma lepszego sposobu na rozwiązanie tego.
P.Brian.Mackey
4

Ponieważ implementacja się zmienia (nie podpis metody), muszę zmienić nazwę metody zamiast tworzyć przeciążenie.

Nie rozumiem. Jeśli implementacja się zmienia, ale podpis nie, dlaczego miałbyś to zrobić? Niech „stara” metoda korzysta z nowej i ulepszonej implementacji. Deweloperzy używający tego interfejsu API będą przewracać oczami, gdy zobaczą metodę z dokładnie taką samą sygnaturą i ostrzeżeniami o wycofaniu w istniejących wywołaniach metod. (Czy możesz sobie wyobrazić czas, kiedy to się kiedykolwiek wydarzyło w API?)

Jeśli nie masz pewności, czy zmiana podstawowej implementacji tej metody będzie działać, sprawdź zachowanie za pomocą testów jednostkowych przed i po zmianie implementacji.

Brian
źródło
To niezły ideał. Problem polega na tym, że nie mamy uprzęży testowych. To kolejna kwestia, którą mam nadzieję rozwiązać. Ponieważ nie ma testów integracyjnych, nie mogę zrobić tego, co zalecasz. Istnieje zbyt wiele nieokreślonych depresji, które nie zostaną przetestowane.
P.Brian.Mackey
Powodem, dla którego wspomniałem o testowaniu, jest to, że wyraźnie chciałeś to zrobić, aby osoby korzystające z Twojego API przeprowadziły testy i pomogły ci znaleźć problemy między dwoma połączeniami. Wydaje się, że najlepszą opcją jest wrzucenie programistów używających twojego kodu do ognia i zmuszenie ich do użycia nowej implementacji, mając nadzieję, że przeprowadzą dokładną kontrolę jakości lub przeprowadzą własne testy.
brian
Rzuciłbym się w ogień. Wolę trzymać się oryginalnego kodu, który opublikowałem. W ten sposób nikt nie dzwoni do mnie o trzeciej nad ranem, zastanawiając się, dlaczego zepsuł się kod produkcyjny. Następnie polegaj na programistach, którzy rozwiążą problem przestarzałości kodu podczas naprawy i naprawią flagi ostrzegawcze. Jeśli nie naprawią tego w tym momencie, to gdy łańcuchy połączeń zaczną na nich zawodzić, to ich wina, że ​​nie naprawili flag ostrzegawczych ... nie mojej.
P.Brian.Mackey
Za każdym razem, gdy piszesz nowy kod, istnieje ryzyko wprowadzenia problemów. Testy pozwolą ci refaktoryzować bez obawy. Strach zabija myślenie. Dodatkowo opóźniasz nieuniknione; niechętnie dodadzą „2” do swojego połączenia kilka iteracji, a otrzymasz ten sam telefon, jeśli to nie zadziała.
brian