Naruszenie zasady OSUSZANIA

10

Jestem pewien, że istnieje gdzieś nazwa tego anty-wzoru; jednak nie znam wystarczająco literatury anty-wzorcowej, aby ją poznać.

Rozważ następujący scenariusz:

or0jest funkcją członka w klasie. Na lepsze lub gorsze, w dużym stopniu zależy to od zmiennych członków klasy. Programator A pojawia się i potrzebuje funkcji, or0ale zamiast wywoływania or0, programista A kopiuje i zmienia nazwę całej klasy. Zgaduję, że ona nie dzwoni, or0ponieważ, jak mówię, jej funkcjonalność jest silnie zależna od zmiennych składowych. A może jest młodszym programistą i nie wie, jak to wywołać z innego kodu. Więc teraz mamy or0i c0(c dla kopii). Nie mogę całkowicie winić programisty A za to podejście - wszyscy mamy napięte terminy i włamujemy się do kodu, aby wykonać pracę.

Wielu programistów utrzymuje, or0więc jest to teraz wersja orN. c0jest teraz wersją cN. Niestety większość programistów, którzy utrzymywali zawieranie klas, or0wydawała się zupełnie nieświadoma - c0co jest jednym z najsilniejszych argumentów, jakie mogę wymyślić dla mądrości zasady DRY. I może istnieć także niezależne utrzymanie kodu w c. Tak czy inaczej wydaje się, że or0i c0były utrzymywane od siebie niezależne. I, radość i szczęście, pojawia się błąd cN, który nie występuje w orN.

Mam więc kilka pytań:

1.) Czy istnieje nazwa tego anty-wzoru? Widziałem to tak często, że trudno mi uwierzyć, że to nie jest nazwany anty-wzór.

2.) Widzę kilka alternatyw:

a.) Napraw, orNaby pobrać parametr określający wartości wszystkich potrzebnych zmiennych składowych. Następnie zmodyfikuj, cNaby zadzwonić orNze wszystkimi potrzebnymi parametrami przekazanymi.

b.) Spróbuj ręcznie przenieść poprawki od orNdo cN. (Pamiętaj, że nie chcę tego robić, ale jest to realistyczna możliwość).

c.) Skopiuj ponownie orNdo - cNznowu, fuj, ale wymieniam to ze względu na kompletność.

d.) Spróbuj dowiedzieć się, gdzie cNjest zepsuty, a następnie napraw go niezależnie od orN.

Alternatywa a wydaje się najlepszym rozwiązaniem na dłuższą metę, ale wątpię, czy klient pozwoli mi ją wdrożyć. Nigdy nie masz czasu ani pieniędzy, aby naprawić problem, ale zawsze masz czas i pieniądze, aby naprawić ten sam problem 40 lub 50 razy, prawda?

Czy ktoś może zasugerować inne podejścia, których mogłem nie brać pod uwagę?

Onorio Catenacci
źródło
„Czy istnieje nazwa tego anty-wzoru?” Anty-wzór „pogwałcająco-suchy”? :) IMHO, sam prawie na to odpowiedziałeś.
Steven Jeuris,
Może nazwać to „The Dry Violator”?
FrustratedWithFormsDesigner
2
Nazywam to: osuszaniem.
AJC
5
Skopiować i wkleić kodowanie?
tylermac
Nazywa się to wzorem „zbyt wielu kucharzy psuje bulion”.
Doc Brown

Odpowiedzi:

18
  1. nazywa się to po prostu duplikatem kodu - nie znam na to żadnych wymyślnych nazw. Długoterminowe konsekwencje są zgodne z opisem i jeszcze gorzej.

  2. Oczywiście wyeliminowanie powielania jest idealną opcją, jeśli tylko jest to możliwe. Może to zająć dużo czasu (w ostatnim przypadku w naszym starszym projekcie miałem kilka metod zduplikowanych w ponad 20 podklasach w hierarchii klas, z których wiele ewolucyjnie powiększyło swoje niewielkie różnice / rozszerzenia w ciągu lat. mi około 1,5 roku poprzez kolejne pisanie testów jednostkowych i refaktoryzację, aby pozbyć się wszystkich duplikatów. Wytrwałość była jednak warta).

    W takim przypadku możesz nadal potrzebować jednej lub kilku innych opcji jako tymczasowych poprawek, nawet jeśli zdecydujesz się zacząć eliminować powielanie. Jednak to, które z nich jest lepsze, zależy od wielu czynników i bez większego kontekstu po prostu zgadujemy.

    Wiele drobnych ulepszeń może na dłuższą metę mieć duże znaczenie. Niekoniecznie potrzebujesz do tego wyraźnej zgody klienta - trochę refaktoryzacji za każdym razem, gdy dotkniesz tej klasy, aby naprawić błąd lub wdrożyć funkcję, może z czasem przejść długą drogę. Po prostu uwzględnij dodatkowy czas na refaktoryzację w swoich szacunkach zadań. To tak jak standardowa konserwacja, aby utrzymać oprogramowanie w dobrej kondycji na dłuższą metę.

Péter Török
źródło
3
+1, jeśli nie tylko za wzmiankę o zduplikowanym kodzie, ale za zwykły wysiłek związany z twoją historią refaktoryzacji kodu. : D
Andreas Johansson
9

Jest odniesienie do wzorca WET (We Enjoy Typing), ale nie wiem, czy jest to standardowa nazwa.

... Licencjonowanie oprogramowania to znaczący wyjątek od praktyki DRY (Don't Repeat Yourself) - kod licencyjny oprogramowania powinien być NAJLEPSZY (MOŻEMY Wpisywać - odwrotnie niż DRY).

Jeśli wyodrębnisz logikę licencjonowania w jednym miejscu, w oderwaniu od innych problemów, znacznie ułatwisz modyfikację oprogramowania, aby całkowicie wyłączyć licencjonowanie. O wiele lepiej jest powtarzać logikę licencjonowania wiele razy w całej aplikacji, najlepiej tak, aby była wykonywana wiele razy podczas jednego uruchomienia oprogramowania.

Na przykład zalecamy sprawdzenie licencji podczas instalacji, uruchamiania aplikacji i przy każdym dostępie do ważnych funkcji. Nie sprawdzaj licencji raz podczas uruchamiania i przekaż tę wartość; zamiast tego faktycznie zreplikuj kontrolę licencji w każdym obszarze. Jest to niewygodne, ale o wiele lepsze niż wypuszczenie produktu, który łatwo złamać ...

jeremy-george
źródło
3
WET może oznaczać: Napisz wszystko dwa razy
StuperUser
1
@StuperUser Odkryłem, że wczoraj na dailywtf ...
-george
3

Jeśli dobrze cię rozumiem, w klasie dzieje się zbyt wiele. To tworzy metody, które nie są zgodne z zasadą pojedynczej odpowiedzialności . Prowadzi do kodu, który musi być przenoszony, fragmenty zabrane, a inne pominięte. Może to również stworzyć wielu członków.

Powinieneś także przejrzeć modyfikatory dostępności. Upewnij się, że rzeczy, które są publiczne, w rzeczywistości powinny być publiczne. Konsument nie musi wiedzieć o każdym małym członku ... użyj enkapsulacji.

To wymaga refaktora. Wygląda również na to, że kod jest pisany bez wstępnego projektu. Zobacz rozwój oparty na testach. Napisz kod, jak powinien być wywoływany, zamiast wywoływać kod, jakkolwiek jest on zaimplementowany. Przejrzyj TDD, aby uzyskać wskazówki na temat wykonania zadania.

P.Brian.Mackey
źródło
3

Jeśli kopiujesz kod, wprowadzisz techniczny dług związany z podwójną konserwacją, a dokładniej: kopiowaniem kodu .

Zwykle jest to naprawiane przez refaktoryzację. Mówiąc dokładniej, przekierowujesz wszystkie wywołania do nowej funkcji (lub nowej metody w nowej klasie), która ma wspólny kod. Najprostszym sposobem na rozpoczęcie jest usunięcie całego skopiowanego kodu i sprawdzenie, co się zepsuło, w którym można to naprawić, przekierowując wywołania do wspólnego kodu.

Uzyskanie zgody klienta na kod refaktoryzacyjny może być trudne, ponieważ trudno jest przekonać osobę nietechniczną do naprawienia długu technicznego. Tak więc następnym razem, gdy podasz szacunkowe dane czasowe, po prostu podaj czas potrzebny na dokonanie refaktoryzacji do swoich szacunków . Przez większość czasu klienci zakładają, że robisz czyszczenie kodu w czasie, gdy robisz poprawki.

Łup
źródło
1

Brzmi jak kod spaghetti . Najlepszym rozwiązaniem jest refaktoryzacja / przepisanie.

pejoratywny termin dla kodu źródłowego, który ma złożoną i splątaną strukturę kontrolną, szczególnie taką, która wykorzystuje wiele GOTO, wyjątków, wątków lub innych „nieustrukturyzowanych” rozgałęzionych konstrukcji. Nazywa się tak, ponieważ przebieg programu jest koncepcyjnie podobny do miski spaghetti, tj. Skręcony i splątany ...

http://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Spaghetti.jpg/175px-Spaghetti.jpg

Tom Squires
źródło
-1 Refaktoryzacja i przepisywanie to dwie bardzo różne opcje. Całkowite przepisywanie, wyrzucanie oprogramowania, nigdy nie jest dobrym pomysłem. joelonsoftware.com/articles/fog0000000069.html
P.Brian.Mackey
1
Kod spaghetti to IMO o wiele bardziej ogólny i luźniejszy termin. Chociaż taki kod często zawiera duplikacje, możesz mieć kod spaghetti bez powielania, a także wysoce zduplikowany, ale nie kod spaghetti.
Péter Török
@ P.Brian.Mackey Nigdy nie powiedziałem, że Refactor i przepisywanie były tym samym. OP powinien zdecydować, którego użyć.
Tom Squires
2
Nigdy nie byłem fanem tego artykułu. Zgadzam się, że przepisywanie było złym pomysłem w przytoczonym przykładzie, ale fakt, że był to zły pomysł w tym przypadku, nie oznacza, że zawsze jest to zły pomysł. Na początek, czy przepisywanie będzie blokować jakiś postęp? Jeśli tak, to źle; jeśli nie, to nie jest tak źle.
jhocking
@jhocking - Uważam, że zasadą braku przepisywania nie jest blokowanie postępu w innych programach, a raczej utrata prawdziwych poprawek w czasie. To magiczne „if (goldenNugget> 22)”, choć źle nazwane, wciąż rozwiązuje konkretny problem, który może być niemożliwy do zidentyfikowania bez godzin lub dni badań. Teraz, biorąc te same dane i je ulepszając, należy zamiast tego zrobić. To jest refaktor. Wyrzucenie go i powiedzenie „zrobimy to następnym razem” to strata czasu. Ten sam powód rozwiązywania już rozwiązanych problemów to strata czasu. Dodanie dobrego kodu
oprócz
0

Mówisz, że nie możesz całkowicie winić A - ale skopiowanie klasy w ten sposób jest w rzeczywistości niewybaczalne. To ogromna porażka w procesie sprawdzania kodu. Jest to prawdopodobnie najbardziej masywna awaria, ponieważ w ogóle nie ma przeglądu kodu.

JEŚLI kiedykolwiek pomyślisz, że musisz stworzyć okropny kod, aby dotrzymać terminu, to absolutnie najwyższy priorytet żądania wydania powinien być naprawienie okropnego kodu TERAZ. Twój problem zniknął.

Zasada OSUSZANIA dotyczy sytuacji, które nie są do końca idealne i można je poprawić. Powielanie klasy to zupełnie nowy kaliber. Najpierw nazwałbym go „zduplikowanym kodem”, az czasem zmieni się w najgorszy ze wszystkich marnotrawców czasu, „rozbieżny powielony kod”: wiele kopii tego samego kodu, które są prawie, ale nie całkiem identyczne, i nikt nie wie, czy różnice są zamierzone, zbieg okoliczności lub błędy.

gnasher729
źródło
-3

Prawie dekadę spóźniono się na tę imprezę, ale nazwa tego anty-wzorca brzmi „ Rozbieżna zmiana” , w której wiele klas zawiera kopie tego samego zachowania, ale wraz z postępem czasu i utrzymania, a niektóre klasy są zapominane, zachowania te się rozchodzą.

W zależności od tego, jakie jest wspólne zachowanie i jak jest ono wspólne, można go zamiast tego nazwać chirurgią strzelby , z tą różnicą, że w tym przypadku wiele klas zapewnia jedną logiczną funkcję, a nie jedną.

doOOooonkeyKoooOOOooong
źródło
1
To nie wygląda tak samo. Zmiana rozbieżna ma miejsce wtedy, gdy wiele zmian wprowadza się w tej samej klasie. OP opisuje duplikację kodu. Chirurgia strzelby też nie jest tym samym. Operacja strzelby opisuje tę samą zmianę dokonaną w kilku różnych klasach.
Robert Harvey,