Подтвердить что ты не робот

Обезьяна-исправление Vs. S.O.L.I.D. принципы?

Я медленно перемещаюсь с PHP5 на Python на некоторые личные проекты, и сейчас я люблю этот опыт. Прежде чем выбраться, чтобы спуститься по маршруту Питона, я посмотрел на Руби. То, что я заметил из сообщества рубинов, заключалось в том, что обезьяна-паттинг была общей и высоко оцененной. Я также наткнулся на много ужасных историй о испытаниях отладки ruby ​​s/w, потому что кто-то включил относительно безвредную библиотеку, чтобы сделать небольшую работу, но которая исправила некоторый сильно используемый основной объект, никому не рассказывая.

Я выбрал Python для (среди других причин) его более чистого синтаксиса и того факта, что он может делать все, что может сделать Ruby. Python делает OO-щелчок намного лучше, чем PHP, и я все больше и больше читаю о принципах OO, чтобы улучшить это понимание.

В этот вечер я читал о принципах Robert Martin SOLID:

  • S принцип ответственности,
  • O ручка/закрытый принцип,
  • L принцип замены iskov,
  • I принцип сегрегации nterface и
  • D принцип инверсии вершин

В настоящее время я до O: ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ (КЛАССЫ, МОДУЛИ, ФУНКЦИИ И Т.Д.) ДОЛЖНЫ БЫТЬ ОТКРЫТЫ ДЛЯ РАСШИРЕНИЯ, НО ЗАКРЫТЫ ДЛЯ МОДИФИКАЦИИ.

Моя голова взволнована из-за конфликта между обеспечением последовательности в дизайне OO и всей палочкой для обезьян. Я понимаю, что его можно сделать в Python. Я также понимаю, что быть "питоническим" - это следовать общим, хорошо проверенным, лучшим практикам и принципам.

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

4b9b3361

Ответ 1

Существует разница между патчами обезьян (переписывание или изменение ранее существовавших методов) и простое добавление новых методов. Я думаю, что последнее прекрасно, и первое должно выглядеть подозрительно, но я все еще поддерживаю его.

Я столкнулся с довольно многими проблемами, когда стороннее расширение monkey передает основные библиотеки и ломает вещи, и они действительно сосут. К сожалению, все они неизменно возникают из-за того, что сторонние разработчики расширений придерживаются наименьшего сопротивления, вместо того, чтобы думать о том, как правильно строить свои решения должным образом. Это отстой, но это не больше, чем ошибка обезглавливания, чем вина изготовителей ножей, которые люди иногда режут сами.

Единственные случаи, когда я когда-либо видел законную потребность в патче для обезьян, - это обходить ошибки в сторонних или основных библиотеках. Только для этого это бесценно, и я действительно был бы разочарован, если бы они убрали способность делать это.

Временная шкала ошибки в программе С#, которую мы имели:

  • Прочитайте странные отчеты об ошибках и проблему с трассировкой для небольшой ошибки в библиотеке CLR.
  • Инвестируйте дни, выходящие с обходным путем, включающие в себя исключения в странных местах и ​​множество хаков, которые много компрометируют код.
  • Потратьте время на удаление хакерских решений, когда Microsoft выпускает пакет обновления

Временная шкала ошибки в программе рельсов у нас была:

  • Прочитайте странные отчеты об ошибках и проблему с трассировкой для незначительной ошибки в стандартной библиотеке ruby.
  • Проведите 15 минут, выполняя небольшую патч-обезьяну, чтобы удалить ошибку из библиотеки ruby, и поместите защитные устройства вокруг нее, чтобы отключиться, если она работает на неправильной версии ruby.
  • Выполняйте обычное кодирование.
  • Просто удалите monkeypatch позже, когда выпущена следующая версия ruby.

Процесс исправления ошибок выглядит аналогичным, за исключением случаев "monkeypatching", 15-минутного решения и 5-секундной "экстракции", тогда как без него возникают боль и страдания.

PS: Следующий пример - "технически" monkeypatching, но разве это "морально" monkeypatching? Я не изменяю никакого поведения - это более или менее просто AOP в рубине...

class SomeClass
  alias original_dostuff dostuff
  def dostuff
    # extra stuff, eg logging, opening a transaction, etc
    original_dostuff
  end
end

Ответ 2

На мой взгляд, monkeypatching полезно иметь, но что-то, что можно злоупотреблять. Люди, как правило, обнаруживают это и чувствуют, что его следует использовать в любой ситуации, где, возможно, более целесообразным может быть смесь или другая конструкция.

Я не думаю, что это то, что вы должны запретить, это просто то, что любят использовать Ruby. Вы можете делать подобные вещи с Python, но сообщество заняло позицию, что все должно быть проще и понятнее.

Ответ 3

Патч обезьян не является рубино-явным, его все делается по всему javascript, с негативными (IMO) эффектами.

Мое личное мнение заключается в том, что исправление обезьяны должно выполняться только

a) Добавьте функциональность к старой версии языка, которая доступна в новой версии языка, который вам нужен.

b) Если для этого нет другого "логического" места.

Есть много многих простых способов сделать исправление обезьяны действительно ужасным, например, возможность изменить, как работают основные функции, такие как ADDITION.

Моя позиция, если вы можете избежать этого, сделайте это.

Если вы можете избежать этого красивым способом, то вам будет приятно.

Если вы не можете этого избежать, получите мнение 200 человек, потому что вы, вероятно, просто не слишком об этом думали.

My pet hate - это mootools, расширяющий объект функции. Да, ты можешь это сделать. Вместо того, чтобы просто узнать, как работает javascript:

setTimeout(function(){ 
    foo(args); 
}, 5000 ); 

Был добавлен новый метод для каждого объекта функции (да, им не шучу), так что функции теперь имеют свои собственные функции.

foo.delay( 5000 , args );

У кого был дополнительный эффект такого рода дерьма:

foo.delay.delay( 500,  [ 500, args ] ); 

И на таком до бесконечности.

Результат? У вас больше нет библиотеки и языка, ваш langauge поклоняется библиотеке, и если библиотека оказывается в области видимости, у вас больше нет языка, и вы не можете просто делать то, что они сделали, когда вы изучаете язык, а вместо этого нужно изучить подмножество команд new, чтобы оно не упало на его лице (за счет чрезмерного замедления!)

могу заметить, что foo.delay также возвратил объект со своими собственными методами, чтобы вы могли сделать

x = foo.delay( 500, args ); 
x.clear(); 

и даже

 x.clear.delay(10); 

который может казаться слишком полезным, но... вы должны принимать во внимание массивные накладные расходы, используемые для обеспечения этой жизнеспособности.

 clearTimeout(x); 

SO HARD!

(Отказ от ответственности: это было некоторое время с тех пор, как я использовал moo, и попытался его забыть, а имена/структура функций могут быть неверными. Это не ссылка на API. Пожалуйста, проверьте их сайт для получения более подробной информации (извините, их ссылка API отстой!)) Суб >

Ответ 4

Mokeypatching обычно ошибочен. Создайте соответствующий подкласс и добавьте методы.

Я использовал monkeypatching один раз в производственном коде.

Проблема заключается в том, что REST использует GET, POST, PUT и DELETE. Но тестовый клиент Django предлагает только GET и POST. У меня есть обезьяна, переданная методы для PUT (например, POST) и DELETE (например, GET).

Из-за жесткой привязки между клиентом Django и тестовым драйвером Django было проще всего обезвредить его, чтобы поддерживать полное тестирование REST.

Ответ 5

Вы можете найти просветительскую эту дискуссию о открытых классах Ruby и принципе открытого закрытия.

Несмотря на то, что мне нравится Ruby, я чувствую, что исправление обезьян - это инструмент последней меры для достижения цели. При прочих равных условиях я предпочитаю использовать традиционные методы ОО с покровом функционального программирования.

Ответ 7

Моя первая мысль заключается в том, что исправление обезьян нарушает OCP, поскольку клиенты класса должны быть в состоянии ожидать, что этот класс будет работать последовательно.

Ответ 8

Обезьяна-исправление просто неверно, ИМХО. Я не сталкивался с принципом открытого/закрытого, о котором вы упоминали раньше, но это принцип, который я давно придерживался, я согласен с ним на 100%. Я думаю об обезьяннике-паттинге как об обонянии кода в большем масштабе, как о запахе кода-философии.