Używanie różnych wzorów dla podobnych funkcji


10

Jestem jedynym programistą w projekcie, który, jak w przypadku każdego projektu oprogramowania, może być zajęty przez kogoś innego w przyszłości.

Powiedzmy, że użyłem wzorca X do implementacji funkcji A. Po opracowaniu i ukończeniu tej funkcji, zdaję sobie sprawę, że mogę zaimplementować tę samą funkcję przy użyciu wzorca Y, o której właśnie się dowiedziałem. Ale funkcja A działa dobrze, a refaktoryzacja z X do Y jest czasochłonna i daje niewielkie korzyści.

Potem nadszedł czas na wdrożenie funkcji B. Jest podobny do A, ale tym razem chcę skorzystać z okazji, aby zagrać ze wzorem Y. Cieszę się z efektu końcowego, lepiej niż podczas wykonywania funkcji A, ale teraz mój kod używa dwóch różne wzory, X i Y, dla podobnych funkcji.

Ale nie ma żadnego rzeczywistego powodu, aby używać różnych wzorów, z wyjątkiem faktu, że podczas budowania elementu AI nie była wystarczająco wykwalifikowana, aby używać tego samego wzoru co dla cechy B.

Zauważ, że to pytanie nie dotyczy wyboru odpowiedniego wzoru dla danego problemu ; chodzi o dwa wzorce współistniejące w bazie kodu w celu rozwiązania podobnych problemów, które można zredukować do jednego, mając wystarczająco dużo czasu na refaktoryzację.

  • Czy ten kod pachnie?
  • Jakie są wady utrzymywania takiego kodu źródłowego?
  • Czy powinienem trzymać się tylko jednego wzoru? tj. refaktor A, aby użyć Y lub nadal używać X podczas pisania B?
  • Jak w źródle mogę przekazać, że powód, dla którego istnieją dwa różne wzorce dla podobnych funkcji, zasadniczo nie ma żadnego powodu?
  • Czy martwię się zbytnio o to, co myśli następny programista o moim kodzie?

Odpowiedzi:


7

Jeśli wzór X i Y rozwiązuje ten sam problem i żaden z nich nie jest obiektywnie lepszy, powinieneś wybrać jeden i trzymać się go. Jeśli to w ogóle możliwe, powinieneś starać się konsekwentnie rozwiązywać ten sam problem.

Jesteś nie martwiąc się zbytnio, raczej jest to poważny zapachy kodu, które powinno się obsługiwać i oczyścić.

Wady różnych rozwiązań tego samego problemu w bazie kodu:

  • zrozumienie kodu zajmie dwa razy więcej czasu
  • modyfikacja kodu zajmie dwa razy więcej czasu po zmianie niektórych zachowań związanych z tym wzorcem
  • będziesz mieć dwa razy więcej błędów
  • obecni i przyszli koledzy będą cię nienawidzić

2

Zgadzam się z odpowiedzią JacquesB . Dodałbym, odpowiadając na inne pytania, że ​​jeśli teraz masz dwa współistniejące wzorce i nie miałeś (jeszcze) czasu, aby dokonać refaktoryzacji aplikacji, aby użyć tego, który okazał się najlepszy, powinieneś że w twoich komentarzach w klasie „obrażającej” (tej do refaktoryzacji). W ten sposób dla przyszłego programisty (ciebie lub kogoś innego) oczywiste jest, że wciąż jest trochę do spłacenia.

Wreszcie główną wadą utrzymywania takiej bazy kodu jest dodatkowa, ale niepotrzebna złożoność. Na pewno chcesz za wszelką cenę uniknąć niepotrzebnej złożoności!


Wolałbym zobaczyć to na jakiejś liście rzeczy do zrobienia lub przynajmniej jako dodatek do notatki w kodzie.
JeffO,

@JeffO Zgadzam się. Chociaż poleganie tylko na listach czynności do wykonania nie jest obarczone dodatkowymi problemami, ponieważ w większości przypadków są one osobiste (niepodzielone), w przeciwieństwie do komentarza w bazie wspólnego kodu. Ale znowu się zgadzam i prawdopodobnie dobrym pomysłem jest posiadanie obu (kiedy na pewno nie da się ich uniknąć na początku).
carlossierra

Trafne spostrzeżenie. Powinna to być coś więcej niż zwykła lista rzeczy do zrobienia obejmująca dzielenie się, współpracę, komunikację i wszystkie inne fajne rzeczy;
JeffO

1

Nie graj w bazie kodu. Napisz prototypy, dzięki czemu możesz znaleźć zalety i wady jednego wzoru / projektu w stosunku do drugiego (innych).

Może się okazać, że to, co intuicyjnie odczuwalne, można zmniejszyć, może być bardziej złożone niż posiadanie 2 różnych wzorów.

Spodziewaj się, że rzucisz dużo kodu opracowanego dla prototypu.


1

To, czy jest to zapach kodu, zależy od tego, jak podobny jest problem A i problem B. Odpowiedź JacquesB wydaje się zakładać, że są one bardzo podobne i że jeśli zmienisz problem A (na przykład w celu usunięcia błędu), będziesz musiał również zmienić problem B w tym samym czasie. JaqueB może mieć rację, ale może się zdarzyć, że A i B zmieniają się niezależnie, ponieważ nie są aż tak podobne. W takiej sytuacji nie jest prawdopodobne, aby opisano wady.

Na podstawie opisu brzmi to jak zapach kodu (powielanie), ale trudno powiedzieć, jak śmierdzi tym zapachem. Na przykład, jeśli A używa metody szablonu, a B używa strategii, dwa problemy mogą być bardzo różne, pomimo zastosowania wzorców dublowania. Poczekam i zobaczę podejście. W przypadku, gdy pojawia się problem C i jest on podobny do A i B, wówczas zmieniłbym A, aby był spójny z B, a następnie utworzenie C powinno być bardzo proste. Jeśli w A jest błąd, chciałbym go również przefiltrować, aby pasował do B, a następnie napraw błąd. W takim razie nic się nie zmieni ... to nie ma znaczenia, prawda?

Posiadanie wielu sposobów rozwiązywania podobnych problemów w bazie kodu jest faktem. Nawet w przypadku, gdy jesteś jedynym programistą, będziesz uczyć się nowych rzeczy i mieć nowe informacje, dzięki czemu Twoje rozwiązania się zmienią. Jak poprawnie rozpoznasz, musisz naprawić te niedoskonałości, jednocześnie zapewniając wartość. Przeprojektowanie (co tak naprawdę robisz po zmianie wzoru) kod, który nigdy się nie zmieni, nie zapewnia wartości. Jedynym prawdziwym sposobem, aby wiedzieć, że to się zmieni, jest faktyczna zmiana, dlatego czekam na problem C.


1

Nie, możesz mieć wiele wzorców używanych w jednej bazie kodu.

Jeśli jednak implementujesz komponent i ujawniasz sposób korzystania z niego zgodny ze wzorcem, prawdopodobnie najlepiej trzymać się tego. Powiedzmy na przykład, że używam wzorca konstruktora dla mojego klienta zapytań REST, ale następnie implementuję jeden z zasobów inaczej. To wprowadzi ludzi w błąd.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.