Wiosenne porządki #3 – Miękki refaktoring

2008-04-10 17:24

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:

  • Wprowadzanie całkiem nowych klas rozszerzających funkcjonalność już istniejących. Można w tym celu wykorzystać agregację (obiekt nowej klasy zawiera obiekt starej), dziedziczenie prywatne czy nawet publiczne. Ważne jest, aby nowa klasa na tyle różniła się od oryginalnej, by jej istnienie było uzasadnione i nie powodowało dylematów pod tytułem “Której klasy mam użyć?…”.
  • Uzupełnienie istniejących klas o nowe metody. Dzięki temu, że nie zmieniamy żadnego z już istniejących składników klasy, stary interfejs nadal będzie dostępny.
  • Dodanie do metod wersji przeciążonych i/lub parametrów domyślnych. Jest to odpowiednik wspomnianego przyrostka 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.

Tags:
Author: Xion, posted under Programming »


7 comments for post “Wiosenne porządki #3 – Miękki refaktoring”.
  1. Riddlemaster:
    April 10th, 2008 o 18:39

    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 ;)

  2. moriturius:
    April 10th, 2008 o 19:06

    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…

  3. yarpen:
    April 10th, 2008 o 21:50

    Autentyczna nazwa f-kcji z pewnego komercyjnego silnika pewnej bardzo znanej firmy – IsHardwareSoundPlaying_PleaseDontUseThis. (co ciekawe, f-kcja wbrew nazwie dziala bezblednie).

  4. Riddlemaster:
    April 10th, 2008 o 23:07

    @yarpen: ta nazwa to zatem dowcip programistów czy założyli, że nie powinna działać (a działała)?

  5. yarpen:
    April 11th, 2008 o 0:30

    Nie mam bladego pojecia, dokumentacji brak :) Zakladamy, ze kiedys nie dzialalo, ale pozniej ktos cos poprawil i nie chcialo mu sie nazwy zmieniac :)

  6. moriturius:
    April 11th, 2008 o 6:55

    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

  7. pozycjonowanie łódź:
    February 24th, 2014 o 19:11

    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!

Comments are disabled.
 


© 2017 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.