Jaki jest dobry, zwięzły sposób wyjaśnienia nie-programistom niebezpieczeństw związanych z programowaniem kopiuj-wklej? [Zamknięte]


27

Szukam dobrej analogii lub metafory, która mogłaby zilustrować problemy związane z programowaniem kopiuj-wklej dla nie-programistów. Od czasu do czasu przeprowadzam przeglądy kodu / systemu dla potencjalnych klientów, a jednym z typowych problemów, które widzę, jest ogromna ilość kodu kopiuj-wklej we wszystkich bazach kodu. Jest to coś, co rutynowo wzywam w recenzjach i za każdym razem muszę wyjaśnić, dlaczego jest to problem (jest to szczególnie trudne w przypadku klientów, którzy wiedzą wystarczająco dużo o programowaniu, aby zrozumieć, że ponowne użycie jest dobre, ale nie wystarczająco, aby zrozumieć, dlaczego kopiuj-wklej nie jest dobrą formą ponownego użycia). Oczywiście potrafię (i robię) wyjaśnić problem w zakresie utrzymania kodu, ale byłoby miło mieć dobrą, zwięzłą analogię do tego problemu, który trafiłby do domu z nie-programistami. Premia, jeśli analogia ilustruje, dlaczego wyszukiwanie i zamiana nie jest skutecznym rozwiązaniem tego problemu. Jakieś sugestie?

Tylko dla wyjaśnienia (na podstawie odpowiedzi Jaroslava poniżej) - nie mówię tu o stosowaniu fragmentów kodu; To, co widzę (niepokojąco często), to kopiowanie i wklejanie rozległych obszarów kodu lub dziesięcioliniowego fragmentu kodu w celu wklejenia niektórych danych użytkownika (wraz z wbudowanym zapytaniem SQL) do dziesiątek stron PHP lub ASP.NET. Powtórz kod z innego miejsca w tym samym projekcie.

Aktualizacja: Jest tu kilka naprawdę dobrych odpowiedzi; W komentarzach wyjaśniłem, dlaczego wybrałem odpowiedź Scotta Whitlocka, ale gorąco polecam również odpowiedź whatsisname, jeśli masz do czynienia z klientami, którzy w ogóle znają się na produkcji.


Hmmm, to trudne. Nie przekłada się to dobrze na analogie klasycznych samochodów / budynków / fabryk .....
whatsisname

3
Wyobraź sobie odniesienia do partii republikańskiej i demokratycznej w amerykańskim prawie zwyczajowym, a następnie zmianę nazwy jednej ze stron przy jednoczesnym dodaniu trzeciej ... wiele przepisów będzie musiało zostać przepisanych.
Job

Co powiesz na analogię: kopiowanie i wklejanie kodu (niepewne, źle ustrukturyzowane itp.), Którego nie rozumiesz na stronach wiki, forach itp., Przypomina otwieranie załączników e-mail (wirusów, programów szpiegujących, spamu itp.) Z osoby trzecie?
sakisk

@faif: Skopiowany kod niekoniecznie musi być śmieciowy. To może być dobry kod, który napisał facet w biurze obok ciebie. Problem z wklejonym kodem polega na tym, że bardzo szybko staje się niemożliwym do opanowania koszmarem konserwacji / debugowania.
whatsisname

1
@faif: następnie zamknij sekcję w nawiasach
whatsisname

Odpowiedzi:


36

To jest tak ... masz jeden zegar w domu. Świetny! Wiesz, która jest godzina, ale zawsze musisz iść do tego jednego pokoju, żeby na to spojrzeć.

Ale oczywiście chcesz wiedzieć, która jest godzina bez ciągłego chodzenia do tego pokoju, więc kupujesz więcej zegarów i rozprowadzasz je po całym domu. Każdy z tych zegarów jest niezależny. Wszyscy zachowują swój czas. To znaczy:

  • Kiedy czas zmienia się z powodu czasu letniego, musisz zmienić je wszystkie
  • Nawet gdy wszystkie są ustawione, wszystkie są nieco inne i rzadko zgadzają się idealnie. Z czasem dryfują.

Teraz wyobraź sobie ten sam problem w dużym obiekcie z dziesiątkami lub setkami zegarów. Dlatego potrzebujesz czegoś takiego jak ten zegar sieciowy, który utrzymuje synchronizację z centralną podstawą czasu. W ten sposób czas jest definiowany raz i tylko raz .

Programowanie z kopiowaniem i wklejaniem jest jak kupowanie większej liczby niezależnych zegarów. Nie skaluje się.


1
Wybrałem tę odpowiedź, ponieważ myślę, że najlepiej sprawdza się w sytuacjach, w których zwykle się znajduję - większość oprogramowania, na które patrzę, jest przeznaczona dla ludzi z sektora usług, a analogie produkcyjne są często trudne do zrozumienia. Ale prawie każdy ma wiele zegarów w swoim domu. Podoba mi się również, ponieważ mogę wykorzystać fakt, że każdy z zegarów w twoim domu prawdopodobnie ma inny proces zmiany czasu (i jest szybki / wolny o inną kwotę) jako sposób na wyjaśnienie, dlaczego wyszukiwanie i zamiana nie są opcja konserwacji kodu kopiuj-wklej.
EZ Hart

38

Wyobraź sobie, że projektujesz samolot. Masz jeden silnik odrzutowy. Dobrze się sprzedaje. Teraz zamierzasz zaprojektować czterosilnikowy samolot na długie rejsy przez ocean.

Teraz nie tworzysz pełnego zestawu specyfikacji technicznych i rysunków dla każdego silnika, prawda? Nie, używasz tego samego silnika we wszystkich czterech miejscach. Teraz wyobraź sobie, że masz 4 zestawy rysunków i musisz coś zmienić. Teraz musisz to zmienić we wszystkich czterech rysunkach silnika. Co się stanie, jeśli przypadkowo zapomnisz coś zmienić w 4. silniku, ponieważ się rozstawiałeś?

Powiedzmy, że zmieniasz długość śruby lub gwintu rury. Teraz nie możesz po prostu „wyszukiwać i zamieniać” w bazie danych rysunków technicznych, możesz przypadkowo zmienić śruby mocujące w pompach paliwowych, ponieważ okazały się mieć ten sam rozmiar. Lub linia hydrauliczna zasilająca ster ogona używała tego samego gwintu, ale teraz jest inaczej i nie można już zasilać ogona.

Teraz wyobraź sobie, że NTSB wprawia Cię w zakłopotanie, ponieważ twoje silniki losowo rzucają łopatkami turbiny i wybuchają podczas lotu na południe od Florydy. Teraz na jakie rysunki silnika patrzysz? Wszyscy, jeden z nich? Skąd wiesz, że wszystkie cztery są takie same? Być może wprowadzono poprawki, ale dotyczą one tylko pierwszego silnika, ponieważ facet, który zaprojektował silniki, opuścił rok temu, aby zagrać w zespole reggae i był jedynym, który pamiętał, że cztery silniki są w osobnych plikach, a facet, który naprawił wybuchającą turbinę, był jego zastępcą.

Kopiowanie i wklejanie kodu jest analogiczne do posiadania zduplikowanych rysunków części składowych, czy to śruby, czy silnika. Chcesz wyodrębnić komponenty do podstawowych elementów, które są ponownie wykorzystywane w jak największym stopniu.

Nie powielaj silników, po prostu napisz kod mocujący silniki do skrzydła.


11
Teraz wyobraź sobie, że silnik numer 4 różni się od pozostałych trzech. Czy ta różnica była zamierzona? Czy jest zaprojektowany, aby przeciwdziałać pewnemu problemowi z momentem obrotowym spowodowanym skręceniem w lewo natychmiast po starcie? A może był to błąd podczas kopiowania?
David Thornley

5
Wielka analogia ... ale jeśli ktoś ma problemy ze zrozumieniem kopiuj / wklej ... silniki odrzutowe kod może być tak samo trudne :)
Steven Evers

W tej analogii powinieneś mówić o rakietach na paliwo stałe zamiast silników odrzutowych. W ten sposób możesz zakończyć: „Widzisz? Tak jak w rakietach”.
detly

To nie jest analogia. Plany są dosłownie kodem artefaktów mechanicznych.
intuicyjnie

7

Musisz to wyjaśnić w kategoriach udostępniania tego samego zasobu, a nie duplikowania tego samego zasobu.

Na przykład, czy miałoby sens, aby każdy dom w dużym mieście miał dedykowaną elektrownię dostarczającą energię elektryczną do domu, czy też byłoby bardziej sensowne, aby każdy dom miał tę samą elektrownię? Jeśli coś pójdzie nie tak z konkretnym komponentem zastosowanym w elektrowni (elektrowniach) i wymagane są naprawy, łatwiej byłoby dokonać napraw w jednym miejscu i wszyscy skorzystają z tych napraw, niż napraw w każdej dedykowanej elektrowni i tylko w każdej świadczenia domowe indywidualnie.


7

„Hey Look wszystko operacja jest nieco podobna rację ?, więc nie miałby nic przeciwko, gdybym przypadkowo skopiować chirurgicznej instrukcje dla różnych procedur z różnych chirurgów do swojej pracy?”


1
Świetny!!! Operacja odbywa się za pomocą noży, prawda? Pozwól, że użyję noża rzeźniczego, aby wykonać operację mózgu na tobie.
Aditya P

1
@AdityaGameProgrammer: Gdy jedynym narzędziem, które masz, jest nóż rzeźniczy, wszystko wygląda jak szynka.
Joey Adams

6

Kopiowanie i wklejanie jest jak próba wyprodukowania części bez formy. Jest powolny, a dostaniesz jednorazowe użycie z każdej części, ponieważ po ustaleniu, że jest uszkodzona lub zepsuta, nie możesz po prostu naprawić formy, aby stworzyć odpowiednią zamiennik.

Poszukując analogii, najpierw musimy wziąć pod uwagę niebezpieczeństwa związane z programowaniem kopiowania i wklejania :

  • Wprowadzono błędy, ponieważ kopia nie jest dokładnie dopasowana (niepotrzebne zmienne i ścieżki kodu nie zostały wyczyszczone)
  • Zwiększone wymagania testowe - abstrakcja pomaga wyeliminować potrzebę testowania regresyjnego, ponieważ testujesz tylko to, co zmieniłeś, i zmieniasz tylko liście, a nie gałęzie.
  • Duplikacja powiela wszystko, w tym błędy. Każda poprawka błędu lub funkcja, która ma zastosowanie do obu sekcji kodu, kosztuje teraz dwa razy więcej do wdrożenia i istnieje duże prawdopodobieństwo, że całkowicie go zapomnisz.
  • Wyszukaj i zamień zaostrza powyższy problem, ponieważ nie można łatwo znaleźć zduplikowanego kodu.

Główną bronią w walce z programowaniem kopiowania i wklejania jest abstrakcja . Aby znaleźć dobrą analogię, poszukaj przykładów abstrakcji w otaczającym nas świecie.

Abstrakcja opiera się na idei tworzenia definicji, a następnie korzystania z nich w trakcie wykonywania. Jaki byłby świat bez definicji?

  • Definicje są kluczową częścią języka prawnego. Wyobraź sobie umowę, która nie miała podstawowych definicji, ale w pełni definiowała każdy termin za każdym razem, gdy była używana.
  • Definicje i szablony są używane w budownictwie. Częstym problemem w konstrukcji jest wykonywanie każdego nowego cięcia na podstawie ostatniego, a nie pojedynczego pomiaru wykonanego na początku. Może to powodować niezwykle różne długości w czasie.
  • Organizacja firmy oparta jest na streszczeniach i definicjach. Co jeśli za każdym razem, gdy Twoja firma musi się rozwijać, musi od nowa zdefiniować nową rolę? To by nie działało. A co jeśli zdecydują się po prostu wybrać podobną rolę i nieznacznie ją zmodyfikować, aby pasowała. Wszyscy byliby zamknięci na miejscu, ponieważ przenoszenie zasobów byłoby niemożliwe.

Kopiowanie ma miejsce tylko wtedy, gdy kopiowany kawałek jest trwały. W przeciwnym razie z każdą kopią powstaje zupełnie nowy oddział - osobno testowany, konserwowany i aktualizowany.

Abstrakcja walczy z tym, wiążąc wszystkie gałęzie razem w jeden pień i izolując modyfikacje mniejszych gałęzi, a nawet liści.


2
Podoba mi się analogia pleśni, reszta, obawiam się, że niewiele pomoże użytkownikom niebędącym technikami.
Matthieu M.,

@ Matthieu - Nie wiem, czy masz na myśli pierwsze punkty, ale nie mówiłem, że to były analogie, opisałem coś, co moim zdaniem jest procesem myślowym dla dewelopera, który myśli o dobrych analogiach.
Nicole,

4

Myślę, że mówisz o zduplikowanym kodzie, a nie o wklejaniu (za pomocą urywków i podobnych).

Oto analogia z książki historycznej, która bardzo dobrze to ilustruje. Przed prasą Gutenberga mnisi siedzieli i ręcznie pisali książki, ciągle przepisując tę ​​samą książkę. Książki, które napisali mnisi, często zawierały błędy i dzięki Gutenbergowi problem ten został wyeliminowany.

Kolejna analogia: bankomaty. Masz jeden bankomat, który może obsługiwać różne karty i zawsze dobrze je obsługuje. Duplikowanie kodu tworzy różne bankomaty, więc każdy musiałby przejść do innego, a czasami maszyna nawet dałaby ci BSOD.

Jest niesamowity artykuł na temat wklejania kopii z Jeffa http://www.codinghorror.com/blog/2009/04/a-modest-proposal-for-the-opy-and-paste-school-of-code-reuse. HTML

PS Wiem, że przed Gutenbergiem była prasa drukarska.


2

Dla nie-programistów zakładam, że rozmawiamy z ludźmi biznesu, więc byłbym krótki i dotyczył realiów pieniężnych.

  1. Każda linia kodu kosztuje pieniądze (pisemne lub skopiowane)
  2. Każdy błąd kosztuje znacznie więcej niż każda linia.
  3. Każda linia kodu dodaje potencjalne błędy
  4. Duplikowany kod = zduplikowane błędy
  5. W tym samym cyklu testowym prawie nigdy nie znaleziono zduplikowanych błędów.

Wytnij i wklej = Burning Money.


1

Czy nie mogę odpowiedzieć na pytanie, ale powiedzieć, że naprawdę nie potrzebujesz tutaj analogii, a próba znalezienia odpowiedniej analogii dla każdego idiomu rozwoju lub wzoru wydaje się przewrotna i często przynosi efekt przeciwny do zamierzonego. To tak, jakby ćwiczyć jogę płaskimi stopami ...

Istnieje kilka powodów, dla których kopiowanie / wklejanie prowadzi do problemów: propaguje istniejące błędy w nowo wklejonych obszarach, w niektórych środowiskach, w których kiedyś uważano je za zwiększenie wydajności, jest teraz wolniejsze (mogę podać przykłady, jeśli ktoś jest zainteresowany, ale sprowadza się to do JIT i czy naprawdę uważasz, że jesteś mądrzejszy niż nowoczesny kompilator?).

Pokazuje, że deweloper jest albo leniwy, albo samolubny, albo jedno i drugie. Jeśli jest to bitwa, w której aktualnie walczysz w zespole, w zależności od swojej pozycji w tej drużynie (kierownik zespołu / jnr dev, snr dev, cokolwiek), musisz ją naprawić, być może w drodze arbitrażu w organizacji.

EDYCJA: W świetle poniższego komentarza, że ​​jest to kod przeglądający kod strony trzeciej w imieniu strony trzeciej (a może nawet czwartej strony :)) Mam nadzieję, że mogę dodać kilka użytecznych rzeczy.

Po pierwsze, kiedy kod został opracowany dla strony trzeciej, czy posiadali jakieś dane? Na przykład linie kodu (LoC).

Nadal uważam, że niektóre z powyższych słów wciąż się liczą. Prawdopodobnie powinienem też zapytać, jaki jest cel przeglądu. Jeśli chcesz uzyskać wycenę w celu jej utrzymania lub zastąpienia, musisz zadać wiele różnych pytań.

Tak czy inaczej, oceniasz jakość kodu, cóż, skopiuj każdą pastę należy do kategorii „Deweloper wykazał się wystarczającym zrozumieniem abstrakcji i / lub projektu kontroli przepływu programu”:

Komentarz: Deweloper nie wykazał się zrozumieniem abstrakcji, a ich podejście do kontroli przepływu programu było podatne na błędy. Tutaj możesz wprowadzić „złożoność cyklomatyczną”. W rzeczywistości jest to dość łatwe do zrozumienia i na okrągło myślę, że mogłem znaleźć odpowiedź: D Tak dla mnie.

Ok złożoność cyklomatyczna jest taka. Masz mapę Ma swoją pozycję początkową i każdy możliwy cel podróży. To nie musi być dużo. Pomyśl, parking, kawiarnia, toaleta. Cyklomatyczna złożoność jest miarą liczby różnych tras, które można dostać się do pozycji początkowej do dowolnego miejsca docelowego.

Skopiowanie i wklejenie kodu prawdopodobnie zwiększy złożoność cykliczną, ponieważ będzie zawierać powtarzalną logikę, którą można by wyodrębnić we własnym nazwanym bloku (lub metodzie).

Wydajesz się rozsądny?


Żeby było jasne, jest to kod napisany przez inne organizacje i jest dostarczany do naszej organizacji w celu sprawdzenia. Więc to nie jest walka w mojej organizacji, ale coś, co muszę sprawić, by ludzie (nie-programiści) z innej organizacji zrozumieli.
EZ Hart

Warto to wiedzieć i sprawia, że ​​znacznie łatwiej jest być przydatnym, mam nadzieję :) Dodam edycję.
Ian

Niestety, długa edycja, ale myślę, że tldr jest kopiowaniem, a wklejony kod jest zapachem kodu, który wskazuje na wzrost złożoności cyklomatycznej (między innymi), a złożoność cyklomatyczna jest bardzo łatwa do opisania za pomocą metafory jednopłaszczyznowej.
Ian

1

Weź angielskie słowo na coś. Teraz wyobraź sobie, że za każdym razem, gdy chcesz to opisać, użyłeś pełnej definicji słownika zamiast samego słowa. Jak łatwo byłoby cię zrozumieć innym?

I tworzą wyobrażenie czegoś, co nie występuje lub nie jest przypadek (wyobrazić) to wykazujący działanie lub stan, który jest uzależniony od drugiego; Prosta przeszłość woli. Wskazanie przyszłości w odniesieniu do przeszłości. Wskazanie działania w przeszłości, które miało miejsce wielokrotnie lub często (byłoby), nie byłoby łatwe; wymagające wielkiego wysiłku fizycznego lub psychicznego, aby osiągnąć, zrozumieć lub znieść (trudne).

Nie zaszkodzi również pokazanie rzeczywistego przykładu przed i po prawdziwym kodzie, który został refaktoryzowany w celu usunięcia duplikacji.


Polecam przećwiczenie drugiego akapitu, aby dostarczyć styl Leslie Nielsen :-)
Karl Bielefeldt

1

Istnieją również obawy dotyczące bezpieczeństwa i integralności kodu.

Jak pokazano tutaj , możliwe jest osadzanie złośliwych danych w znakach Unicode, które są przenoszone do schowka.

W zależności od tego, jak Twój edytor reaguje na znaki Unicode, może to spowodować nieoczekiwane zmiany w kodzie źródłowym, nieoczekiwane wyniki kompilatora lub pewne rzeczy, o których jeszcze nie pomyślałem.


0

Widzę tutaj kilka różnych tras:

  1. Plagiat - Niektórzy mogą pamiętać to ze szkoły, w której kradzież własności intelektualnej jest wielkim nie-nie. Program do kopiowania i wklejania może wyglądać tak, ponieważ ktoś może nie rozumieć źródła lub tego, co może pochodzić z używania konkretnego rozwiązania, które zostało po prostu ślepo skopiowane i wklejone bez analizy, jak to działa, i nie rozumiem, dlaczego tak się dzieje lub nie. skuteczne rozwiązanie problemu.

  2. Ślepe podążanie za wskazówkami - Większość ludzi prawdopodobnie miałaby doświadczenia z dotarciem do miejsca, w którym wcześniej nie była. Niektórzy mogli użyć MapQuest lub Google Maps, aby znaleźć miejsce, a następnie postępować zgodnie z podanymi wskazówkami. Były historie o tym, że ludzie gubią się lub po prostu nie znajdują miejsca, w którym powinni być, mimo że oprogramowanie zawierało szczegółowe instrukcje, jak się tam dostać. To inne duże niebezpieczeństwo kopiowania i wklejania polega na tym, że to tak, jakby ktoś właśnie podał ci wskazówki dojazdu z punktu A do punktu B, nie pozwalając zobaczyć żadnej mapy obszaru, która może utrudnić podróż. Jeśli to nie wydaje się trudne, możesz podnieść stawkę, prosząc osobę, aby przedostała się z A do B w opasce, aby musiała polegać na innych zmysłach, aby określić kierunek, w którym się znajduje i dotrzeć do celu.

Dane, informacje, wiedza i mądrość mogą być dobrym modelem, do którego można się odwołać, aby pokazać, dlaczego wyszukiwanie i zamiana nie są skuteczne jako rozwiązanie, ponieważ kopiowanie i wklejanie jest bardzo mechaniczne i nie wymaga wiele myślenia, więc przesyłane dane mogą być bez wiedzy i mądrości właściwego korzystania z niego. Można by spojrzeć na energię jądrową, aby zobaczyć przykłady tego, jak zrozumienie różnicy może być dość potężne. Porównaj reaktor jądrowy z bombą nuklearną pod względem bezpieczeństwa i użyj, aby zobaczyć, jak wiedza, co się dzieje, nie wystarczy, aby bezpiecznie wykorzystać moc atomu.


0

Wyobraź sobie, że masz grupę uczniów i zbiór zasad dla szkoły. Zamiast zamieszczać reguły we wspólnym miejscu, wszyscy uczniowie muszą odnieść się do każdej z nich, egzemplarz zasad. Każdemu uczniowi mówi się, że musi postępować zgodnie z kopią zasad zawartych w liście.

Teraz zmodyfikuj jedną z zasad mówiących, że w przypadku katastrofy powinieneś udać się do nowego schronu. Musisz iść do każdego ucznia i zmodyfikować jego zestaw zasad. Jeśli jeden z uczniów zginie i tornado uderzy, uczeń pójdzie do starego miejsca i umrze straszną śmiercią.


0

Ktoś wysyła Ci wiadomość e-mail z załączonym szablonem dokumentu. Możesz go używać do momentu zmiany szablonu. Nie martw się, nie zapomną wysłać Ci odświeżonej kopii.


0

Model kosztów CoCoMo.

http://en.wikipedia.org/wiki/COCOMO

Zastosowany wysiłek (E) = a * (KLOC) ** b, gdzie b> 1,0

Ten wykładnik oznacza, że ​​wysiłek związany z budowaniem / utrzymywaniem / obsługą / przepisywaniem rośnie szybciej niż liczba wierszy kodu.


0

Jest jeszcze jeden ważny aspekt tej złej praktyki, którego nikt jeszcze nie wziął pod uwagę: ślepo kopiując (pełny lub częściowy) kod od kogoś innego ( bez jego zgody ) możesz łamać prawa autorskie .


0

Widzę kodowanie kopiuj-wklej, w którym programista nie rozumie lub nie chce uzasadnić tego, co robi, i kopiuje razem różne części, które już robią „mniej więcej” to, czego potrzebują, losowo przesuwając je na końcu aby pasowały do ​​siebie.

Są z tym trzy główne problemy:

  1. Nigdy nie powoduje kodu wolnego od błędów. Zawsze.
  2. Jeśli nie zrozumieli kodu podczas pisania, nigdy nie mogliby go zrozumieć podczas debugowania. Tylko ktoś inny może wyczyścić bałagan, który popełnił, za dodatkową opłatą.
  3. Jeśli unikają myślenia o pisanym kodzie, unikają nauki. Jeśli unikną nauki, nigdy nie będą dobrym programistą. Jeśli nigdy nie będą dobrym programistą, dlaczego są w twoim zespole?

0

Załóżmy, że masz 5 koleżanek (szczwany pies) i chcesz wysłać im wszystkim wiadomość walentynkową. Wpisujesz pierwszą literę, dodajesz jej imię i wspominasz coś niezapomnianego, które udostępniłeś. Następnie czterokrotnie kopiujesz i wklejasz list, za każdym razem brakuje instancji imienia dziewczyny nr 1 za pomocą funkcji kopiuj i wklej, ponieważ popełniłeś literówkę. Teraz 4 z twoich pięciu dziewczyn są w drodze do domu dziewczyny nr 1.

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.