몽키 패칭은 좋은 프로그래밍 관행으로 간주됩니까?


15

나는 몽키 패칭 이 표준적이고 좋은 프로그래밍 관행보다는 빠르고 더러운 해킹 범주에 더 가깝다 는 인상을 받았다 . 때때로 타사 라이브러리의 사소한 문제를 해결하는 데 사용되었지만 임시 수정 사항을 고려하여 타사 프로젝트에 적절한 패치를 제출했습니다.

그러나, 나는 Gevent의 예를 들면 주류 프로젝트에 "정상적인 방법」로서 사용되는이 기술은, 본 적이 gevent.monkey모듈을 .

몽키 패칭이 일반적이고 수용 가능한 프로그래밍 방식이 주류가 되었습니까?

Jeff Atwood의 "Monkeypatching For Humans" 참조


13
나는 원숭이 패치 라고 불리는 것이 좋은 프로그래밍 연습으로 간주 되지 않는다고 말할 것 입니다. 그 이름으로 만 알 수 있습니다.
littleadv

타사에서 필요한 수정을 수행하지 않으려면 어떻게합니까?

1
@ Thorbjørn : 좋은 질문, 한편으로는 monkeypatching을 좋아하지 않습니다. 다른 한편으로는 프로젝트를 복제하고 로컬 패치를 사소한 문제로 생각하는 것을 좋아하지 않습니다.
vartec

1
@littleadv : ... 그런 다음 "핫 픽스"/ "온더 플라이 픽스"또는 "런타임 픽스"라고 부르는데 제대로 들리나요? ;) 모두 동일합니다.
dagnelies

3
자바 스크립트는 개념을 중심으로 거의 구축
ZJR

답변:


19

아니요, 그러나 때때로 monkeypatch는 코드를 깨뜨린 것보다 덜 악합니다. 루비의 몽키 패치에 대한 나의 일반적인 규칙은 다음과 같습니다.

  • monkey-patch에 대한 충분한 이유가 있습니다 (임시 중요 핫픽스가 좋은 이유입니다. ActiveSupport에서 작업하지 않는 한 to_s 메소드의 형식이 좋지 않습니다).

  • 가능한 한 투명하게 만드십시오 : 코드베이스의 특정 위치에 파일을 넣고 파일을 분리하고 monkeypatch의 이유를 설명하는 문서를 작성하십시오 (여기에 예가 있습니다) ).

  • 쉽게 제거-문서에는 제거 및 감시 대상에 대한 정보가 포함되어야합니다. 많은 monkeypatches는 일시적이므로 제거하기 쉬워야합니다.


11

예, monkeypatching은 매우 유용합니다!

어쨌든 이름은 사람들의 인식에 큰 영향을 미치는 것 같습니다. "monkeypatch"라고 부르고 나쁘게 들리면 "핫픽스"또는 "온더 플라이"라고 부르면 좋습니다.

그것과는 별도로, 런타임에 메소드 / 속성 / 함수를 변경하는 기능은 매우 유용한 것이라고 생각합니다. 자바 스크립트 사용자조차도 하루 종일 모르게 사용합니다.

예를 들어 :

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

이 간단한 라인은 버튼의 동작을 변경한다는 사실을 보여줍니다. 그런 식으로 설계되었습니다. 마찬가지로, 다른 모든 기능을 변경할 수는 있지만 어리석은 일입니다.

이제 패치를 이런 식으로 전달해야한다는 질문에 대해. 큰 릴리스 대신 작은 패치 만 다운로드하면됩니다. 서버를 멈추지 않고 패치 할 수도 있습니다. 그런 다음 언젠가 더 큰 업데이트를 위해 최신 릴리스를 가져올 수도 있습니다. 그럴 수 있지. 예, "런타임 패치"에 투표하는 것이 좋습니다.

흥미롭게도 Erlang과 같은 일부 언어는이 개념을 중심으로 구축되었습니다. 서버를 즉시 업데이트하는 기능.

물론 결국에는 다른 모든 것과 마찬가지로 사용 방법의 문제입니다. 당신은 멋진 OO 물건과 시끄러운 것을 만들 수 있습니다. 모두 동일합니다.

편집하다:

자신의 라이브러리를 패치하든 타사를 패치하든 상관없이 대소 문자 구분을 추가하겠습니다. .

... 기본적으로 이러한 패치로 수행하는 작업은 자신 또는 타사 라이브러리 버그를 수정하는 것 입니다. 두 경우 모두 유용합니다. 직접, 그것은 당신이 즉석에서 수정을 제공 할 수 있습니다. 타사의 경우 스스로 해결 할 때까지 (몇 달?) 기다리거나 지금 혼자서 수행하십시오. (여전히 패치를 제출하여 패치를 자신의 측면에서 수정하도록 할 수 있습니다). 문제가 해결 된 다음 lib 버전을 릴리스 해도 원하는 경우 여전히 할 수 있습니다 라이브러리를 업데이트하고 패치를 제거 .

물론, 패치를 사용하여 lib의 동작을 변경하고 그 목적 / 작업 방식을 소외시키는 것은 분명히 재난의 요리법입니다. 원숭이조차도 볼 수 있었을 것입니다. ;)


1
아무도 유용하지 않다고 말합니다. 그러나 일반적으로 좋은 방법은 아닙니다. 그리고 "hotfix"와 "on-the-fly-fix"는 나에게 더 잘 들리지 않습니다.
Lukas Stejskal

1
글쎄, 나는 응용 프로그램의 동작을 변경하는 기능이 매우 유용하다는 것을 알았습니다. 심지어 이전 방법을 백업으로 저장하는 코드와 필요할 때 자동으로 롤백하는 명령을 가질 수도 있습니다! 가능성은 엄청납니다!
dagnelies

강력하고 유용한 기능이라는 데 동의합니다. 그러나 매우 위험합니다 (Ruby에서 특히). 여러 개의 원숭이 패치 된 타사 라이브러리에 따라 응용 프로그램을 유지하려고 시도한 적이 있습니까? 라이브러리를 업데이트하려고 할 때마다 재난에 대한 레시피.
Lukas Stejskal

1
예, 부주의하게, 의도하지 않은 방식으로 또는 악용하여이 패치를 사용하면 빠르게 혼란스러워 질 수 있습니다. 당신이 어떤 개념을 남용하거나 무엇이든 엉망으로 만들 수 있습니다. 그러나 그렇지 않으면 잘 정리되고 투명하고 다음 큰 릴리스에서 모두 흐르면 깨끗해 보입니다. ... 그러나 나는 패치가 많이 된 루비 라이브러리에 대한 경험이 없습니다.
dagnelies

... 후자의 경우에 대한 의견을 추가했습니다.
dagnelies

8

모든 패치는 런타임 특성으로 인해 본질적으로 위험하며 디자인 타임에 포착 할 수 없다고 생각합니다.

런타임 예외를 환영하며 복잡한 디버거와 감시가 필요합니다.

사람들이 SEAL 수업을 할 때 사용되므로 상속이 불가능합니다. 그러나 객체를 손상시키지 않고 확장 할 수있는 더 좋은 방법이 있습니다.

내 두 센트


4

일반적으로 패치는 최후의 수단이어야하며, 원숭이 패치는 더욱 그러합니다. 이 문제는 주로 유지 관리 가능성 중 하나입니다.

오래 전에 리눅스 커널에는 비디오 카드 드라이버와 내가 소유 한 두 개의 독점 응용 프로그램에 필요한 3 개의 개별 패치가 적용되었습니다. 그중 두 가지가 상충되는 변경 사항이 있었기 때문에 차이점을 해결하려면 4 번째 패치가 필요했습니다. 이제 업스트림 커널에서 보안 문제가 해결 될 때마다이 패치 3 개 공급 업체가 새 커널 버전에 대한 업데이트를 릴리스 할 때까지 기다려야했습니다. 1-6 개월이 걸리거나 업스트림을 수동으로 유지 관리해야했습니다. 다른 패치 공급 업체가 따라 잡을 때까지 보안 패치.

몇 년 후, 벤더들은 업스트림 커널 소스에 참여할 수 있었고, 밸런싱 행위를 멈출 수 있었지만, 그 동안 어떤 혼란이 있었는지 알 수있었습니다. 필요한 경우가 아니면 프로그래머에게 영향을주지 마십시오.


3

아닙니다. 소프트웨어 개발을위한 표준 기술이 아닙니다. 심각한 문제를 해결하는 해결 방법으로 남아 있으며 명확한 단점이 있습니다. Liskov 대체 원칙 위반 오릅니다. 원숭이 패치는 프로그램에 대한 추론을 심각하게 어렵게 만듭니다. 자체 프로그램의 경우 코드를 속한 곳에 배치해야합니다. 타사 라이브러리의 경우 패치가 다음 버전의 라이브러리에서 작동하지 않을 위험이 항상 있습니다.

물론 원숭이 패치는 수행중인 작업을 알고 있고 SOLID 솔루션 을 구현할 시간이없는 경우에 유용합니다 . 하지만 절대로 이것을 표준 기술로 생각 원숭이 패치에 원숭이 패치를 구축 .

BTW, 원숭이 패치에 대한 단위 테스트를 작성한 적이 있습니까?


LSP를 신청할 수는 없다고 생각합니다. 하위 유형과 관련하여 매우 구체적인 정의가 있습니다.
Konrad Rudolph

@KonradRudolph Monkey 개체를 패치하면 유형이 변경됩니다. 동적으로 유형이 지정된 언어에서 유형 u와 동일한 인터페이스를 가진 모든 유형 t는 u의 하위 유형입니다. 오리처럼 걷는다면 ...
scarfridge

“… 유형을 바꾼다”– 충분히 공정하다. 말이된다.
Konrad Rudolph

RE "소프트웨어 개발을위한 표준 기술은 아니다.", 테스트를 위해 파이썬에서 * 항상 주요 라이브러리에서 수행되는 것으로 보인다.
Tommy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.