Kiedy piszemy jakieś klasy, wydaje nam się, że dokładnie przemyśleliśmy ich interfejs, który jest intuicyjny, łatwy w użytkowaniu, wydajny, rozszerzalny, i tak dalej. Musi tak być, skoro sami go napisaliśmy, prawda? ;-) Cóż, życie niestety aż nazbyt często weryfikuje to jakże naiwne założenie. A wtedy pozostaje nam przyjrzeć się, co zaprojektowaliśmy nie dość dobrze i próbować to zmienić.
Jest tylko jedno “ale”: do chwili, gdy zdecydujemy się na zmiany w interfejsie, nasza klasa może być już wykorzystywana w innych fragmentach projektu lub zgoła nawet w innych projektach. To może dotyczyć i takich, których nie jesteśmy autorami – jeżeli tylko zdecydowaliśmy się udostępnić naszą twórczość szerszej publiczności. A wtedy sprawa staje się co najmniej problematyczna, bo każda nieprzewidziana modyfikacja może spowodować kaskadę kolejnych zmian, jakie trzeba będzie poczynić w odpowiedzi na nią.
Jeśli naturalnie bardzo tego chcemy możemy je wszystkie przeprowadzić. Wówczas przynajmniej nasz interfejs będzie znów elegancki – przynajmniej do czasu, gdy stwierdzimy, że znów już taki nie jest ;] Jest to jak najbardziej możliwe, ale pewnie nie trzeba wspominać, jak pracochłonna może być taka operacja.
Spójrzmy raczej na sposób, w jaki radzą sobie z tym problemem twórcy szeroko wykorzystywanych bibliotek programistycznych różnego rodzaju. To, co jest ich cechą wspólną w kolejnych wersjach, to zachowywana zawsze kompatybilność wstecz. Jest ona osiągana przez modyfikacje polegające wyłącznie na dodawaniu elementów interfejsu bez zmiany już istniejących. Pewnie najbardziej znanym przejawem takiej praktyki jest istnienie funkcji z końcówką Ex
w Windows API, które robią trochę więcej niż ich “zwykłe” odpowiedniki i mają nieco zmienioną listę parametrów.
To oczywiście nie jedyna droga nieinwazyjnego poprawiania interfejsu. Takich sposobów jest co najmniej kilka, jak chociażby:
Ex
. Zauważmy, że po takiej operacji możemy zmienić implementację starych metod tak, aby wewnętrznie korzystały one z nowych, rozszerzonych wersji. Póki nie zmieni się sposób ich wywoływania, kod pozostanie kompatybilny wstecz.Można się zastanawiać, czy taki “miękki refaktoring” nie jest odkładaniem na później tego, co i tak należy wykonać? Zapewne tak: przecież każdy kod można zawsze napisać lepiej, czyli od nowa :) Trzeba jednak odpowiedzieć sobie na pytanie, czy korzyści z tego będą większe niż włożony wysiłek. Jeżeli nie kodujemy jedynie dla samej przyjemności kodowania, to nie ma cudów: odpowiedź najczęściej będzie negatywna.
Według mnie rozwiązaniem całkiem w porządku wobec siebie i osób korzystających z naszego kodu jest oznaczenie metod jako deprecated (i wyplucie odpowiedniego komunikatu w outpucie podczas kompilacji). Po pewnym czasie (np. w następnej wersji lub w jeszcze następnej) bez problemów możemy usunąć lub diametralnie zmienić niechcianą metodę bez większych skrupułów (bo przecież ostrzegaliśmy).
Zresztą ja jestem zdania, że jeśli coś musi zostać zrefaktoryzowane to nie należy z tym zwlekać, bo jest to tylko opóźnianie skutków problemu znanego jako paskudny kod. Trzeba być Agile ;)
Myślę, że Riddlemaster ma rację. Jak ktoś chce budować kod za pomocą jakiejś starej funkcji to może sobie ściągnąć starą wersję biblioteki.
Uważam, że nie ma sensu straszyć użytkowników potworami takimi jak to często widywaliśmy w WinAPI.
Swoją drogą – najbardziej denerwują mnie zapisy typu: argument_x – not used…
Autentyczna nazwa f-kcji z pewnego komercyjnego silnika pewnej bardzo znanej firmy – IsHardwareSoundPlaying_PleaseDontUseThis. (co ciekawe, f-kcja wbrew nazwie dziala bezblednie).
@yarpen: ta nazwa to zatem dowcip programistów czy założyli, że nie powinna działać (a działała)?
Nie mam bladego pojecia, dokumentacji brak :) Zakladamy, ze kiedys nie dzialalo, ale pozniej ktos cos poprawil i nie chcialo mu sie nazwy zmieniac :)
To musiał być jakiś dowcip programistów bo przecież nikt z nas nie nazywa funkcji x_NieUzywajcieTego tylko ją po prostu wywala albo komentuje. Chyba, że jestem inny :P
Good day! I could have sworn I’ve been to this blog before but after reading through some of the post I realized it’s new to
me. Nonetheless, I’m definitely delighted I found it
and I’ll be bookmarking and checking back often!