“Fix Everything”디자인 패턴은 무엇입니까?


74

이러한면에서 linuxdevcenter.com에 스티븐 피긴스 2003 기사 , 브램 코헨의 비트 토 런트는 "모든 수정"디자인 패턴을 사용하여 설명한다.

BitTorrent를 이해하기 어렵지만 연구 할 가치가있는 덜 일반적인 접근 방식은 Cohen의 dem 등식을 사용하는 것입니다. 프로세스를 두 번 이상 적용하면 더 이상 변경되지 않습니다. 코헨 대변인은 "모두 수정 (Fix Everything)"이라고하는 디자인 패턴을 사용하고 있으며, 실제로는 변경 될 수있는 모든 사항에 유의하지 않고 여러 변경 사항에 반응 할 수있는 기능입니다. 그는 "일어났던 사건에 주목하고,이 dem 등식으로 작성된 모든 문제 수정 기능을 호출하고, 진행중인 모든 것을 정리하고 처음부터 다시 계산합니다."라고 설명합니다. dem 등식 (Idempotence)은 계산을보다 어렵게 만들지 만 약간 복잡하게 만듭니다. 통화가 무엇을 바꿀지 항상 명확하지는 않습니다. 미리 알 필요는 없습니다. 함수를 자유롭게 호출 할 수 있습니다.

이것은 그것의 얼굴에 아주 좋은 소리.

그러나 dem 등성 "모든 것을 고치십시오"기능을 호출하면 효율성 비용으로 시스템의 견고성이 향상되고 포함 시스템을 잠재적으로 망칠 수 있습니다 (신중하게 계획하고 실행하는 프로세스를 선호 할 수 있음).

그래도 전에 사용했다고 말할 수는 없습니다. 또한 온라인 자신의 응용 프로그램의 소스를 찾을 수 없습니다 (그러나 나는 발견했다 이 하나 그것을 기반으로 주장하고있다.). 이 기사 이외의 참고 ​​문헌도 찾을 수 없으며 (Google-fu가 꽤 좋다고 생각하지만) SOApatterns.org 에서 "Idempotent Capability"에 대한 항목을 찾지 못했습니다 .

이 아이디어가 다른 이름으로 더 잘 알려져 있습니까?

"Fix Everything"디자인 패턴은 무엇입니까? 장단점이 무엇입니까?


4
이름이 함수의 고정 점, x = f (x) 의 아이디어에 대한 참조라고 생각합니다 . x에 f 를 여러 번 적용 하더라도 결과는 같습니다. 올바른 결과를 얻으면 올바른 결과를 다시 처리하면 동일한 올바른 결과가 반환됩니다.
9000

7
누구나 원하는 이름을 지정할 수 있지만 잘 알려진 소프트웨어 패턴은 아닙니다. Idempotency는 그 자체로 잘 알려진 개념입니다. 여기서 창의적으로 사용되고있는 것 같습니다.
Robert Harvey

1
이것은 메인 이벤트 루프가 Mac OS에서 어떻게 구현되었는지를 상기시켜줍니다. 모든 이벤트에 응답하는 단일 기능으로 일반적으로 모든 컨트롤의 상태를 테스트하고 필요에 따라 전체 UI를 업데이트하도록 구성되었습니다. 참으로 dem 등합니다.
Lucas

3
This sounds quite nice on the face of it. 정말? 나에게 끔찍한 소리!
Michael

3
@Michael 당신은 패키지 관리자를 좋아하지 않습니까? 그것들은 같은 개념으로, 더 작은 규모로 작동합니다 : 시스템에 원하는 것을 표시하고, "모든 것을 고치십시오"를 실행하고, 적절하게 설치 / 제거 / 업그레이드하지만 변경이있을 경우에만 할 일이 있습니다.
이즈 카타

답변:


100

하나의 드롭 다운에서 무언가를 선택하거나 다른 컨트롤이 나타나거나 세 번째 컨트롤의 값이 변경 될 수있는 상당히 복잡한 HTML 페이지가 있다고 가정 해 봅시다. 이것에 접근 할 수있는 두 가지 방법이 있습니다 :

  1. 해당 컨트롤의 이벤트에 응답하고 필요에 따라 다른 컨트롤을 업데이트하는 각 컨트롤마다 별도의 처리기를 작성하십시오.

  2. 페이지의 모든 컨트롤 상태를보고 모든 것을 고치는 단일 핸들러를 작성하십시오 .

두 번째 호출은 "idempotent"입니다. 반복해서 호출 할 수 있고 컨트롤은 항상 올바르게 정렬됩니다. 첫 번째 통화에는 통화가 유실되거나 반복되는 경우 (예 : 처리기 중 하나가 토글을 수행하는 경우) 문제가있을 수 있습니다.

두 번째 호출의 논리는 조금 더 애매하지만 처리기 하나만 작성하면됩니다.

또한 "안전한 측면에 있도록"필요에 따라 "모두 수정"기능을 호출하여 항상 두 솔루션을 모두 사용할 수 있습니다.

두 번째 접근 방식은 상태가 다른 소스 (예 : 사용자 입력 대 서버에서 렌더링)에서 올 수있는 경우에 특히 좋습니다. ASP.NET에서는 페이지를 렌더링 할 때마다 모든 항목 수정 기능을 실행하기 때문에이 기술은 포스트 백 개념과 매우 잘 어울립니다.

이벤트가 손실되거나 반복되고 다른 소스에서 상태를 얻는 것에 대해 언급 했으므로이 접근 방식이 BitTorrent와 같은 문제 공간에 어떻게 잘 매핑되는지는 분명합니다.

단점? 분명한 단점은 항상 모든 것을 처리하는 것이 덜 효율적이기 때문에 성능 저하가 있다는 것입니다. 그러나 BitTorrent와 같은 솔루션은 스케일 업이 아닌 스케일 아웃되도록 최적화되어 있으므로 이러한 종류의 작업에 적합합니다. 해결하려는 문제에 따라 적합하지 않을 수 있습니다.


9
MVC는 "Fix Everything"의 전형 인 것 같습니다. 모델을 수정하고 뷰를 처음부터 다시 그리면 작업이 잠재적으로 어떤 부분에 영향을 줄 수 있는지 확인하지 않고 뷰가 완전히 다시 그려집니다.
Matthieu M.

3
이것은 본질적으로 Saltstack, Ansible 및 Nix와 같은 시스템의 기본 원리와 비슷합니다. 구성에 대한 설명이 주어지면 이론적으로 여러 다양한 시스템을 동일한 최종 상태로 만들 수 있습니다.
kojiro

1
@MatthieuM. 프론트 엔드 개발에서 매우 인기가있는 React 는 가상 돔
디핑을 제외

2
@Izkata React보다 훨씬,이 답변은 Redux를 생각하게했습니다.
Kevin

2
"모두 수정"과 and 등원이 다른 것임을 지적하는 것이 유용 할 수 있습니다. "모두 수정"은 일반적으로 dem 등원이지만 (필요하지는 않지만), dem 등원 연산은 모든 것을 고치거나 성능을 가질 필요가 없습니다. 페널티-두 번 실행될 때 동일한 결과를 제공합니다.
Hans-Peter Störr

15

나는 기사를 읽었을 때 실제로 정통이나 새로운 아이디어가 아니기 때문에 기사가 약간 오래되었다고 생각합니다. 이 아이디어는 실제로 단순한 Observer 구현 일 때 별도의 패턴으로 표시됩니다. 당시에 내가 한 일을 되돌아 보면 상호 의존적 인 데이터가있는 여러 다른 패널이있는 다소 복잡한 인터페이스 뒤에 앉아 논리를 작업하는 것을 기억합니다. 사용자는 값을 변경 및 / 또는 최적화 루틴을 실행할 수 있으며 이러한 조치를 기반으로 UI가 수신 및 업데이트하는 이벤트가 생성되었습니다. 개발 중에 특정 패널이 업데이트 될 때 업데이트되지 않는 많은 문제가있었습니다. 수정 (디자인 내에 머물러 있음)은 다른 이벤트에서 이벤트를 생성하는 것이 었습니다. 궁극적으로 모든 것이 제대로 작동 할 때까지 거의 모든 변경으로 인해 모든 패널이 새로 고쳐졌습니다. 주어진 패널을 새로 고쳐야 할 때 분리하려고하는 모든 복잡성은 사라졌습니다. 그리고 그것은 어쨌든 중요하지 않았습니다. 효과적으로 조기 최적화되었습니다. 모든 것을 새로 고치는 단일 이벤트로 모든 것을 축소하여 시간과 노력을 크게 절약했을 것입니다.

"모든 것을 고치거나"모든 것을 새로 고치도록 설계된 수많은 시스템이 있습니다. 행을 추가 / 업데이트 한 다음 DB를 다시 쿼리하는 모든 CRUD 인터페이스를 생각하십시오. 이것은 이국적인 접근 방식이 아니며 명백한 비 영리한 솔루션 일뿐입니다. 2003 년에는 '열병'의 높이라는 것을 알아야합니다. 내가 알 수 있듯이 사람들은 새로운 패턴을 명명하는 것이 명성과 부를 향한 길이라고 생각했습니다. 잘못 이해하지 마십시오. 패턴의 개념은 초록의 솔루션을 설명하는 데 매우 유용합니다. 그냥 일종의 난간을 벗어났습니다. 일반적으로 패턴 개념에 대해 많은 냉소를 만들었 기 때문에 불행합니다. 이 맥락에서 '정통'솔루션으로 이것을 말하는 것이 합리적입니다. 그것' ORM 또는 DI 컨테이너 주변의 정통과 유사합니다. 사람들이 이러한 도구가 존재하기 오래 전에 소프트웨어를 구축해 왔지만 많은 경우에 이러한 도구가 과도하게 사용 되더라도이를 사용하지 않는 것은 정통적인 것으로 여겨집니다.

다시 '모든 것을 고치십시오'. 간단한 예는 평균 계산입니다. 간단한 해결책은 숫자를 합산하고 값의 카디널리티로 나누는 것입니다. 숫자를 추가하거나 수정하면 처음부터 다시 수행하면됩니다. 합계와 숫자의 수를 추적 할 수 있으며 누군가 숫자를 추가하면 수를 늘려 합계에 추가합니다. 이제 모든 숫자를 다시 추가하지 않습니다. 범위를 참조하는 수식으로 Excel을 사용하여 해당 범위의 단일 값을 수정 한 적이 있다면 '모든 항목 수정'패턴의 예가 있습니다. 즉, 해당 범위에 대한 참조가있는 수식은 그 값은 관련이 있습니다 (예 : sumif ()와 같은 것을 사용).

이것은 이것이 주어진 맥락에서 현명한 선택이 아니라고 말하는 것은 아닙니다. 평균 예에서 이제 업데이트를 지원해야한다고 가정하겠습니다. 이제 어떻게 든 이전 값을 알아야하고 델타로 합계를 변경해야합니다. 분산 환경이나 동시 환경에서이 작업을 시도 할 때까지이 중 어느 것도 어려운 일이 아닙니다. 이제 모든 종류의 까다로운 타이밍 문제를 처리해야하므로 결국 재 계산보다 훨씬 속도가 느려지는 주요 병목 현상이 발생할 수 있습니다.

여기서 결론은 '모든 것을 고치십시오'또는 '모든 것을 새로 고치십시오'접근 방식이 훨씬 쉽게 얻을 수 있다는 것입니다. 보다 정교한 접근 방식을 만들 수는 있지만 훨씬 더 복잡하므로 결함이있을 가능성이 높습니다. 또한 많은 맥락에서 '모두 새로 고침'접근 방식이 더 효율적일 수 있습니다. 예를 들어, copy-write 방식은 일반적으로 단일 스레드 방식의 경우 속도가 느리지 만 동시성이 높은 경우 잠금을 피하여 성능을 향상시킬 수 있습니다. 다른 경우에는 효율적인 방식으로 변경 사항을 일괄 처리 할 수 ​​있습니다. 따라서 대부분의 문제의 경우,이를 수행 할 수없는 특정한 이유가없고 필요한 경우 더 복잡한 작업을 수행하는 것에 대해 걱정하지 않는 한 모두 새로 고침 방법으로 시작하려고합니다.


2
나는 Excel에서 다시 계산 모든 셀을 트리거 할 수있는 방법이 왜 단지 인 변화에 의존하는 세포를 다시 계산하고자 확신 해요 : superuser.com/questions/448376/... 나는 것이 가정 (는 "모든 것을 해결" )
Aaron Hall

@AaronHall 만약 그렇다면, 그것은 정말 나쁜 구현입니다. 예를 들어 60,000 개의 셀을 계산하기 위해 15-30 분 동안 7 개의 CPU를 100 % 사용하는 것을 정기적으로 봅니다. 계산은 복잡하지 않습니다. 필자는 종종 파이썬 시작을 포함하여 몇 초 안에 시트의 모든 것을 할 수있는 파이썬 프로그램을 작성했습니다. 이것이 얼마나 오래 걸릴 수 있는지에 대한 최선의 추측이었습니다. 내가 생각했던 다른 것이 될 수 있습니다. Excel에는 실제로 오래된 버그가 많이 있으며 그 기능의 원인 일 수 있습니다.
JimmyJames

1
@AaronHall 해당 사용자는 시트에서 자동 계산을 사용하지 않을 수도 있습니다. Enter 키를 누를 때마다 15 분이 걸리지 않기 때문에 종종 큰 통합 문서에서이 작업을 수행합니다.
JimmyJames

@AaronHall 조금 더 생각하고 포인트가 있습니다. 내 가정은 지나치게 광범위했을 것이다. 더 자신감이있는 것에 더 집중하여 답변을 업데이트했습니다.
JimmyJames

2
@JimmyJames : 내가 의도 한 요점은 최상의 접근 방식은 상황에 따라 크게 다를 수 있으며 "모든 것을 고치십시오"는 "개별적으로 변경 될 때마다 모든 것을 고치십시오"및 "모든 변경이 완료된 후 모든 것을 게으르게 고칠 수 있음"으로 세분 될 수 있다는 것입니다. ".
supercat

4

이것이 "디자인 패턴"인지는 확실하지 않지만 , Puppet, Chef 또는 Powershell DSC의 맥락에서 이러한 유형의 동작을 최종 상태 구성 또는 원하는 상태 구성 으로 분류합니다 .

이러한 솔루션은 일반적으로 문제가 설명하는 비즈니스 논리 수준이 아니라 시스템 관리 수준에서 작동하지만 사실상 동일한 패러다임이지만 이러한 도구는 일반적으로 선언적이지만 절차 적 코드 또는 스크립팅에 동일한 원칙을 적용 할 수 있습니다.


1

나는 주로 사용자 인터페이스 내에서 이것을 사용했습니다. 좋은 점은 한 번 작성하면 가장 간단한 경우에서 가장 어려운 경우까지 모든 것을 똑같이 잘 처리한다는 것입니다 (예 : 사용자가 화면을 회전하는 경우 또는 사용자가 창 크기를 조정하면 거의 모든 것이 변경되는 경우 랩톱 / 데스크탑) ).

효율성에 대해 걱정할 이유가 없습니다. 사용자 인터페이스에서 값 비싼 것은 이동 한 항목을 다시 그리는 것과 같습니다. 각 항목의 위치와 크기는 대개 매우 빠릅니다. 당신이 확인해야 할 것은 당신이 아이템이 속한 장소에 정확하게 머물러야 할 때마다, 그것을 이동시키기위한 코드가 실행되지 않는다는 것입니다. 실제 변화는 당신이 어쨌든해야 할 모든 것입니다.


0

반응 형 프로그래밍 원리와 비슷합니다. "Fix everything"은 현재 "core"상태를보고 영향을 받아야하는 다른 모든 것- "computed states"를 전파합니다. 이 파생을 최적화하면 고효율 a-la React에 도달 할 수 있습니다. 순진한 성능은 아직 충분히 빠르지 만 최적이 아닐 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.