Чи сприйняття мавп вважається хорошою практикою програмування?


15

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

Тим НЕ менше, я бачив цю техніку , використовувану в якості «звичайним способом» в основних проектах, наприклад , в GEvent в gevent.monkeyмодулі .

Чи стала маніпуляція мавпами звичайною, нормальною, прийнятною практикою програмування?

Дивіться також: "Маніпулювання мавп для людей" Джеффа Етвуда


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

Що робити, якщо третя сторона не хоче виконати потрібне виправлення?

1
@ Thorbjørn: гарне запитання, з одного боку мені не подобається маніпулювання, з іншого мені не дуже подобається ідея клонування проекту та збереження локальних патчів, якщо це лише незначна проблема.
vartec

1
@littleadv: ... тоді називаємо це "гарячим виправленням" / "виправленням на ходу" або "виправленням часу виконання", і це звучить добре? ;) Це все одно.
dagnelies

3
javascript в значній
мірі

Відповіді:


19

Ні, але іноді monkeypatch - це менше зло (ніж зламаний код :)). Мої загальні правила щодо мавпочок в рубіні:

  • є справді вагома причина для патч-мавпи (тимчасове критичне виправлення є вагомою причиною. Приємного форматування методу to_s немає, якщо ви не працюєте на ActiveSupport)

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

  • простий у видаленні - документація повинна містити інформацію про видалення та на що слідкувати. Багато папок мавп є тимчасовими, тому їх слід легко видалити.


11

Так, маніпулювання дуже корисно!

Іноді імена здаються дуже впливовими на сприйняття людей. Назвіть це "monkeypatch", і це звучить погано, назвіть його "гарячим виправленням" або "виправленням на ходу", і це звучить добре.

Незалежно від цього, я думаю, що можливість зміни методів / атрибутів / функцій під час виконання - дуже корисна річ. Навіть користувачі JavaScript користуються ним цілий день, не знаючи цього.

Наприклад:

button.onclick = function(e) { ...}

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

Тепер щодо питання доставки патчів таким чином ... ну ... чому б ні. Вам просто потрібно завантажити невеликий патч замість великого випуску. Чорт забирай, ти навіть можеш виправити сервер, не зупиняючи його, чудово! А потім, одного дня, ви також можете отримати останню версію для більшого оновлення. Справедливо. Так що так, я голосую за "виправлення часу", як добру справу.

Цікаво, що деякі мови, такі як Ерланг, навіть будувались навколо цієї концепції. Можливість оновлення сервера на ходу.

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

Редагувати:

Дозвольте додати деякі відмінності у випадку, будь то виправлення власної бібліотеки чи сторонньої .

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

Тепер, звичайно, якщо ви використовуєте патч, щоб змінити поведінку lib та відчужувати її мету / спосіб роботи, то, очевидно, це рецепт катастрофи. Навіть мавпа побачила б це ... ну, сподіваюся. ;)


1
Ніхто не каже, що це не корисно. Однак загалом це не є хорошою практикою. І "виправлення" та "виправлення на ходу" мені не здаються кращими.
Лукаш Штайскал

1
Ну, я вважаю, що можливість змінити поведінку програми під час руху дуже корисно, навіть більше, якщо вона є великою. Чорт забирай, у вас навіть може бути код, що зберігає старий метод, як резервне копіювання та команда автоматично відкатати на вимогу! Можливості величезні!
dagnelies

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

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

... Я додав кілька коментарів до останньої справи.
dagnelies

8

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

Вони вітають винятки під час виконання та вимагають складних налагоджувачів та годинника лише для цього.

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

Мої два центи


4

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

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

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


3

Ні. Це не стандартна методика розробки програмного забезпечення. Залишається вирішити гостру проблему і має чіткі недоліки. Порушення принципу заміни Лісков приходить до тями. Патчі з мавпами значно важче міркують про програми. Для власних програм ви повинні розмістити код там, де він належить. Для сторонніх ліб ви завжди будете небезпечні, що ваш патч не працюватиме з наступною версією.

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

До речі, ти коли-небудь писав одиничний тест на патч мавпи?


Я не думаю, що ви можете тут застосувати LSP. Він має дуже специфічне визначення щодо підтипів.
Конрад Рудольф

@KonradRudolph Мавпа, що виправляє об'єкт, змінює його тип. У динамічно набраних мовах кожен тип t з тим же інтерфейсом, що і тип u, є підтипом u. Якщо вона ходить, як качка ...
хустка

"… Змінює свій тип" - досить справедливо. Має сенс.
Конрад Рудольф

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