Який хороший, стислий спосіб пояснити небезпеку програмування копіювальної пасти для непрограмістів? [зачинено]


27

Я шукаю хорошу аналогію чи метафору, яка могла б проілюструвати проблеми програмування копіювальної пасти для непрограмістів. Іноді я роблю кодові / системні огляди для потенційних клієнтів, і одна з найпоширеніших проблем, яку я бачу, - це велика кількість копіювально-вставного коду по всій їх кодовій базі. Це я звичайно закликаю в оглядах, і кожен раз мені доводиться пояснювати, чому це проблема (це особливо складно з клієнтами, які знають просто програмування, щоб зрозуміти, що повторне використання - це добре, але недостатньо, щоб зрозуміти, чому copy-paste не є гарною формою повторного використання). Очевидно, я можу (і це роблю) пояснити проблему з точки зору обслуговування коду, але було б непогано мати хорошу, стислу аналогію цієї проблеми, яка б потрапила додому з непрограмістами. Бонус, якщо аналогія ілюструє, чому пошук і заміна не є ефективним рішенням цієї проблеми. Будь-які пропозиції?

Просто для уточнення (на основі відповіді Ярослава нижче) - я не говорю тут про використання фрагментів коду; Що я бачу (тривожно часто) - це копіювання та вставлення великої кількості коду чи десятирядковий фрагмент коду для отримання деяких даних користувачів (у комплекті з вбудованим запитом SQL), вставлених на десятки сторінок PHP або ASP.NET. Отже, копіюйте код з інших місць того ж проекту.

Оновлення: Тут є кілька справді хороших відповідей; Я пояснив у коментарях, чому я вибрав відповідь Скотта Вітлока, але я також дуже настійно рекомендую відповідь whatsisname, якщо ви маєте справу з клієнтами, які взагалі знайомі з виробництвом.


Гммм, це важко. Це не добре перекладається на класичні аналогії автомобіля / будівлі / заводу .....
whatsisname

3
Уявіть, що у загальному законодавстві США є посилання на республіканську партію та демократ, а потім перейменування однієї із сторін, додавши третю ... багато законів доведеться переробити.
Робота

Як щодо аналогії: копіювання-вставлення коду (незахищений, погано структурований тощо), якого ви не розумієте з вікі, форумів тощо, подібне до відкриття вкладень електронної пошти (вірусів, шпигунських програм, спамів тощо) від сторонніх?
sakisk

@faif: Копіювати вставлений код не обов’язково код сміття. Це може бути гарним кодом, який написав хлопець в офісі поруч з вами. Проблема коду, вставленого з копією, полягає в тому, що він дуже швидко стає некерованим кошмаром технічного обслуговування / налагодження.
whatsisname

1
@faif: тоді запам’ятовуйте розділ, розміщений в дужках
whatsisname

Відповіді:


36

Це так ... у вас вдома один годинник. Чудово! Ви знаєте, який час, але завжди потрібно зайти до тієї кімнати, щоб подивитися.

Але ви, звичайно, хочете знати, що саме час, не відвідуючи цю кімнату весь час, тому ви купуєте ще кілька годинників, і ви роздаєте їх по дому. Кожен з цих годинників незалежний. Всі вони тримають свій час. Це означає:

  • Коли час змінюється через літній час, вам доведеться змінити їх
  • Навіть коли вони все налаштовані, вони всі трохи відрізняються і рідко ідеально домовляються. З часом вони дрейфують.

Тепер уявіть ту саму проблему у великому закладі з десятками чи сотнями годинників. Ось чому вам потрібно щось подібне до мережевого годинника, який підтримує синхронізацію з центральною базою часу. Таким чином час визначається один раз і лише один раз .

Програмування копіювання та вставки - це як придбання більше незалежних годин. Це не масштабується.


1
Я вибрав цю відповідь, тому що думаю, що вона найкраще працює в ситуаціях, в яких я зазвичай перебуваю - більшість програмного забезпечення, на яке я дивлюся, призначене для людей у ​​сфері послуг, і виробничі аналогії їм часто важко зрозуміти. Але майже всі мають у своєму будинку кілька годинників. Мені це також подобається, тому що я можу використати той факт, що кожен із годинників у вашому домі, ймовірно, має інший процес зміни часу (і швидкий / повільний на різну кількість) як спосіб пояснити, чому пошук і заміна isn не є можливістю підтримувати код копіювання-вставки.
EZ Hart

38

Уявіть, що ви проектуєте літак. У вас є один реактивний двигун. Це добре продається. Тепер ви збираєтеся сконструювати чотиридвигун літака для довгих перевезень через океан.

Тепер ви не створюєте повний набір технічних характеристик та креслень для кожного окремого двигуна, чи не так? Ні, ви використовуєте один і той же двигун у всіх чотирьох місцях. А тепер уявіть, якби у вас було 4 набори малюнків, і вам доведеться щось змінити. Тепер ви повинні змінити його на всіх чотирьох кресленнях двигуна. Що станеться, якщо ви випадково забудете щось змінити в 4-му двигуні, тому що ви відстали?

Тому скажіть, що ви змінюєте довжину гвинта чи різьблення труби. Тепер ви не можете просто «шукати і замінювати» у своїй базі даних інженерних креслень, ви можете випадково змінити кріпильні гвинти в паливних насосах, оскільки вони були однакового розміру. Або гідравлічна лінія, що живить хвостовий руль, використовувала ту саму нитку, але зараз вона інша, і хвоста більше не можна живити.

А тепер уявіть, що вас турбує NTSB, оскільки ваші двигуни випадково кидають лопаті турбіни і вибухають під час польоту на південь від Флориди. Тепер, які креслення двигуна ви дивитесь? Усі вони, один з них? Звідки ти знаєш, що всі четверо однакові? Можливо, виправлення внесені, але вони застосовуються лише до одного двигуна, тому що хлопець, який сконструював двигуни, залишив рік назад, щоб грати в реггі-діапазоні і був єдиним, хто пам’ятав, що чотири двигуни знаходяться в окремих файлах, і хлопець, який виправив вибухну турбіну, був його заміною.

Копіювати та вставляти код аналогічно тому, що мають дублюючі креслення складових частин, будь то гвинт або двигун. Ви хочете абстрагувати компоненти до основних фрагментів, які максимально повторно використовуються.

Не дублюйте двигуни, просто напишіть код, який кріпить двигуни до крила.


11
Тепер уявіть, що ви виявили, що двигун №4 відрізняється від інших трьох. Чи була призначена ця різниця? Чи призначений він для протидії певній проблемі крутного моменту, викликаній поворотом ліворуч відразу після зльоту? Або це була помилка в копіюванні?
Девід Торнлі

5
Чудова аналогія ... але якщо хтось має труднощі з розумінням копіювати / вставляти код ... реактивні двигуни можуть бути настільки ж складними :)
Стівен Еверс

Ви повинні говорити про ракети на твердому паливі замість реактивних двигунів для цієї аналогії. Таким чином, ви можете закінчити з "Дивіться? Так само, як і в ракетній науці".
detly

Це не аналогія. Креслення - це буквально код механічних артефактів.
інтуїтоване

7

Ви повинні пояснити це з точки зору спільного використання одного і того ж ресурсу проти дублювання одного і того ж ресурсу.

Наприклад, чи має сенс кожен будинок у великому місті мати спеціалізовану електростанцію, яка подаватиме електроенергію дому, чи було б більше сенсу, щоб кожен будинок ділився однаковою електростанцією? Якщо щось піде не так із певним компонентом, що використовується на електростанціях (-ах), і потрібні ремонти, було б простіше зробити ремонт в одному місці, і кожен отримає користь від цих ремонтів, порівняно з ремонтом на кожній спеціалізованій електростанції та лише на кожній пільги на будинок індивідуально.


7

"Гей, дивіться, вся хірургія дещо схожа ? Так, тож ви не заперечуєте, якщо я випадково копіюю хірургічну інструкцію для різних процедур у різних хірургів для вашої операції?"


1
Чудово !!! Хірургія робиться ножами так? Дозвольте мені використовувати нож М'ясника, щоб зробити операцію на мозку на вас.
Aditya P

1
@AdityaGameProgrammer: Коли єдиний у вас інструмент - м'ясний ніж, все виглядає як шинка.
Джої Адамс

6

Копіювати та вставляти - це як намагатися виготовити деталі без форми. Це повільно, і ви отримаєте разове використання від кожної деталі, оскільки, як тільки буде визначено, що вона несправна або зламана, ви не можете просто виправити форму, щоб створити відповідну заміну.

У пошуках аналогії спочатку ми повинні врахувати небезпеку програмування копіювання та вставки :

  • Помилки введено, оскільки копія не відповідає правильності (непотрібні змінні та кодові шляхи не очищені)
  • Підвищені вимоги до тестування - абстракція допомагає усунути необхідність регресійного тестування, оскільки ви перевіряєте лише те, що змінили, і ви змінюєте лише листя, а не гілки.
  • Копіювання дублює все, включені помилки. Кожне виправлення помилок або функція, що застосовується до обох розділів коду, тепер коштує вдвічі більше, ніж реалізувати, і велика ймовірність забути його повністю.
  • Пошук і заміна посилює вищевказану проблему, оскільки ви не можете легко знайти дублюваний код.

Основна зброя в боротьбі з програмуванням копіювання та вставки - абстракція . Тож, щоб знайти хорошу аналогію, шукайте приклади абстракції у навколишньому світі.

Абстракція ґрунтується на ідеї встановлення визначень та подальшого використання цих визначень у виконанні. Яким був би світ без визначень?

  • Визначення є ключовою частиною юридичної мови. Уявіть собі контракт, який не мав основних визначень, але повністю визначав кожен термін щоразу, коли він використовувався.
  • Визначення та шаблони використовуються в будівництві. Поширеною проблемою в будівництві є створення кожного нового розрізу на основі останнього, а не на одному вимірюванні, зробленому на початку. Це може призвести до різко різної тривалості з часом.
  • Організація компанії базується на рефератах та визначеннях. Що робити, якщо кожен раз, коли ваша компанія повинна була розширюватися, вони повинні були визначати нову роль з нуля? Це не вийшло. То що робити, якщо вони вирішать просто вибрати подібну роль для роботи та трохи змінити її на відповідну. Кожен був би замкнений на своєму місці, оскільки неможливо перемістити ресурси.

Копіювання має місце лише тоді, коли фрагмент, який копіюється, є постійним. В іншому випадку кожна копія робить цілком новим відділенням, з яким потрібно працювати - тестувати, підтримувати та модернізувати окремо.

Абстракція бореться з цим, зав’язуючи всі гілки разом в одне стовбур і виділяючи модифікації на більш дрібні гілки або навіть листя.


2
Мені подобається аналогія цвілі, решта, боюся, не збираються багато допомагати користувачам, які не користуються технологіями.
Матьє М.

@Matthieu - Я не знаю, чи ви маєте на увазі перші пункти кулі, але я не говорив, що це аналогії, я описував те, що, на мою думку, є мислительним процесом для розробника, щоб думати про хороші аналогії.
Ніколь

4

Я думаю, ви говорите про дублікат коду, а не про копіювання вставлення (використовуючи фрагменти тощо).

Ось аналогія з книги історії, яка це дуже добре ілюструє. Перед пресою Гутенберга ченці сиділи і писали книги вручну і переписували ту саму книжку знову і знову. Книги, які писали ченці, часто були з помилками, і завдяки Гутенбергу цю проблему було усунено.

Ще одна аналогія: банкомати. У вас є один банкомат, який може обслуговувати різні картки і завжди добре їх обслуговує. Копіюючий код створює різні касові машини, тому кожному доведеться переходити до іншого, а іноді машина навіть дає вам BSOD.

Існує дивовижна стаття про вставку копій від Джеффа http://www.codinghorror.com/blog/2009/04/a-modest-proposition-for-the-copy-and-paste-school-of-code-reuse. html

PS Я знаю, що перед Гутенбергом була друкарня.


2

Для непрограмістів я припускаю, що ми розмовляємо з діловими людьми, тому я був би стислим і залучав реальність грошей.

  1. Кожен рядок коду коштує вам грошей (будь то написаний чи скопійований)
  2. Кожна помилка коштує вам набагато більше, ніж кожен рядок.
  3. Кожен рядок коду додає потенційні помилки
  4. Скопійований код = дублювання помилок
  5. Скопійовані помилки майже ніколи не зустрічаються в одному і тому ж циклі тестування.

Вирізати та вставити = Спалювання грошей.


1

Не можу я відповісти на запитання, але сказати, що вам насправді не потрібна аналогія, і намагання знайти правильну аналогію для кожної ідіоми або картини розвитку здається збоченою і часто є протипродуктивною. Це як намагатися займатися йогою плоскостопості ...

Є кілька причин, через які копіювання / вставлення призводить до проблем, вона розповсюджує наявні помилки в нещодавно вставлені області, в деяких середовищах, де раніше це вважалося підвищенням продуктивності, насправді зараз повільніше (я можу навести приклади, якщо хтось зацікавлений, але це зводиться до JIT, а також ти справді думаєш, що ти розумніший за сучасний компілятор?).

Це показує, що розробник або ледачий, або егоїстичний, або те й інше. Якщо це бій, який ви ведете в команді на даний момент, залежно від вашої позиції в цій команді (команда веде / jnr dev, snr dev, що завгодно), вам потрібно це виправити, можливо, арбітражем у вашій організації.

EDIT: У світлі коментаря нижче, що це перегляд коду стороннього коду від імені третьої сторони (або, можливо, навіть четвертої сторони :)) Є кілька корисних речей, які я можу сподіватися.

По-перше, коли код розроблявся для третьої сторони, чи були у них якісь метрики? Наприклад, рядки коду (LoC).

Я все ще думаю, що дещо з того, що я сказав вище, все ще вважається. Напевно, я також повинен був запитати, яка була мета огляду. Якщо ви хочете отримати пропозицію, або замінити її, вам доведеться задати багато різних питань.

Так чи інакше, ви оцінюєте якість коду, ну а копіювання будь-якої пасти підпадає під категорію "Розробник показав адекватне розуміння абстракції та / або дизайну управління потоком програми":

Коментар: Розробник не виявив розуміння абстракції, і їх підхід до управління потоком програми був схильний до помилок. Ви можете ввести тут "Цикломатичну складність". Це насправді досить легко зрозуміти, і в цілому, я думаю, що я міг би знайти відповідь: D Так, для мене.

Добре Цикломатична складність така. У вас є карта. Він має ваше стартове положення та всі можливі пункти призначення. Це не повинно бути багато. Подумайте, автостоянка, кафе, туалет. Цикломатична складність - це показник кількості різних маршрутів, щоб дістатися до початкового положення до будь-якого пункту призначення.

Копіювання та вставлений код, ймовірно, збільшить цикломатичну складність, оскільки він буде включати повторювану логіку, яка могла бути абстрагована у власному названому блоці (або методі).

Вам здається розумним?


Щоб було зрозуміло, це код, який написали інші організації, і він передається нашій організації на розгляд. Тож це не битва всередині моєї організації, а щось, що мені потрібно, щоб люди (непрограмісти) з іншої організації зрозуміли.
EZ Hart

Це корисно знати і полегшує мені корисність, сподіваюся :) Я додам редагування.
Ян

Вибачте, довго редагуйте, але я думаю, що tldr - це копія, а вставлений код - запах коду, який вказує на збільшення циклічної складності (серед іншого), а цикломатичну складність дуже легко описати, використовуючи метафору, що є одногранною.
Ян

1

Візьміть для чогось англійське слово. Тепер уявіть, щоразу, коли ви хотіли описати цю річ, ви використовували повне визначення словника, а не просто слово. Як легко було б для вас зрозуміти інших?

Я формую ментальний образ того, чого немає або чого немає (уявіть) це Позначає дію чи стан, що є умовою іншого; Просте минуле волі. Вказівка ​​на майбутнє відносно минулого часу. Вказати на дію в минулому, що траплялося неодноразово або звичайно (було б), буде зовсім непростим; що вимагає великих фізичних чи розумових зусиль для досягнення чи осмислення чи витримки (важко).

Також не завадить показати фактичний до і після прикладу реального коду, який було відновлено для видалення дублювання.


Рекомендую репетирувати другий абзац, щоб поставити стиль Леслі Нільсен :-)
Карл Білефельдт

1

Також є проблеми безпеки та цілісності коду.

Як продемонстровано тут , можна вбудувати шкідливі дані в символи unicode, які передаються в буфер обміну.

Залежно від того, як ваш редактор реагує на символи unicode, це може призвести до несподіваних змін вашого вихідного коду, несподіваних результатів компілятора або деяких речей, про які я ще не думав.


0

Є декілька різних маршрутів, які я міг бачити, переходячи сюди:

  1. Плагіат - Дехто може згадати це ще зі школи, де крадіжка інтелектуальної власності - це велика ні-ні. Програмування копіювання-вставки може бути таким самим, оскільки хтось може не зрозуміти джерело або те, що може виникнути за допомогою конкретного рішення, яке було просто сліпо скопійовано та вставлено, не аналізуючи, наскільки добре це працює, і зрозуміти, чому це може бути, а може і не бути ефективне рішення проблеми.

  2. Сліпо слідуючи вказівкам - Більшість людей, мабуть, мали б досвід потрапити в якесь місце, де раніше не були. Деякі, можливо, використовували MapQuest або Карти Google, щоб знайти місце, а потім дотримуйтесь наведених вказівок. Існували історії про те, що люди загубляться або просто не знаходять, де вони повинні бути, хоча програмне забезпечення дало конкретні вказівки, як дістатися. Ще одна велика небезпека копію-вставлення полягає в тому, що це так само, якби хтось просто дав вам вказівки проїхати від пункту А до пункту В, не дозволяючи вам бачити будь-яку карту місцевості, яка може зробити поїздку трохи складніше. Якщо це не здається важким, ви можете підняти антену, попросивши людину дістатися від А до В, одягнену із зав'язаними очима, щоб їм довелося покластися на інші органи чуття, щоб визначити, в якому напрямку вони стикаються, і дістатися до цілі.

Дані, інформація, знання та мудрість можуть бути хорошою моделлю, на яку можна посилатися, щоб показати, чому пошук і заміна не є ефективними як рішення, оскільки копіювання та вставка є дуже механічним і без особливих роздумів, щоб передані дані могли бути без знання та мудрості правильного його використання. Можна подивитися на ядерну енергію для прикладів того, як розуміння різниці може бути досить потужним. Контрастуйте ядерний реактор з ядерною бомбою з точки зору безпеки та використання, щоб зрозуміти, як знати лише те, що відбувається там, де недостатньо для безпечного використання сили атома.


0

Уявіть, що у вас є студенти групи та набір правил для школи. Замість того, щоб публікувати правила в загальному місці, всі студенти повинні посилатись, щоб ви передали кожному копію правил. Кожному студенту кажуть, що він повинен дотримуватися своєї копії правил до листа.

Тепер модифікуйте одне з правил, яке говорить про те, що у випадку катастрофи вам слід їхати до нового притулку для катастроф. Ви повинні піти до кожного учня та змінити його набір правил. Якщо когось із студентів пропустять і смерч вдарить, студент піде на старе місце і помре жахливу смерть.


0

Хтось надсилає вам електронний лист із доданим шаблоном документа. Сміливо продовжуйте користуватися ним, поки шаблон не зміниться. Не хвилюйтесь, вони не забудуть надіслати вам оновлену копію.


0

Модель вартості CoCoMo.

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

Прикладне зусилля (E) = a * (KLOC) ** b, де b> 1,0

Цей показник означає, що зусилля зі створення / підтримки / підтримки / переписування зростають швидше, ніж кількість рядків коду.


0

Є ще один важливий аспект цієї поганої практики, який ще ніхто не брав до уваги: ​​сліпо копіюючи (повний або частковий) код з когось іншого ( без їх дозволу ), ви можете порушити закони про авторські права .


0

Кодування копіювальної пасти, яку я бачу, - це те, де розробник не розуміє або не хоче пояснювати, що вони роблять, і копіює разом різні частини, які вже роблять «більш-менш» те, що їм потрібно, випадковим чином переміщуючи їх у кінці щоб вони зблизилися.

З цим є три основні проблеми:

  1. Це ніколи не призводить до помилок без коду. Колись.
  2. Якщо вони не зрозуміли код під час написання, вони ніколи не зможуть розібратися в ньому під час налагодження. Тільки хтось інший може очистити безлад, який вони зробили, за додаткову плату.
  3. Якщо вони уникають думати про код, який вони пишуть, вони уникають навчання. Якщо вони уникають навчання, вони ніколи не будуть хорошими програмістами. Якщо вони ніколи не стануть хорошим програмістом, чому вони в вашій команді?

0

Скажімо, у вас є 5 подруг (ви лукаві собаки), і ви хочете надіслати всім валентинки. Ви набираєте першу букву, додаєте її ім’я та згадуєте щось пам’ятне, яким ви поділилися, хлопці. Потім ви копіюєте та вставляєте лист чотири рази, кожен раз пропускаючи екземпляр імені дівчини №1 з копією та вставкою, оскільки ви зробили друк. Тепер 4 з ваших п’яти подруг на шляху до будинку подруги №1.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.