"알림 센터"패턴이 프로그램 설계를 좋게 또는 나쁘게 조장합니까?


13

때때로 나는 코코아 NSNotificationCenter 예를 들어,이 메시지 허브 스타일의 API를 건너 : http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/Reference/Reference.html

일반적으로 이러한 API는 메시지 / 이벤트를 구독하거나 브로드 캐스트하는 글로벌 액세스 지점을 제공합니다. API에서 명시 성이 없지만 소스 코드에 숨겨져있는 평평하고 구조화되지 않은 프로그램 아키텍처를 장려하기 때문에 이것이 문제라고 생각합니다. 객체 소유권과 계층 구조에 대해 생각할 필요는 없지만 프로그램의 객체를 사용하여 호출되는 코드를 만들 수 있습니다. 그러나 이것은 좋은 것입니까?

이 패턴이 일반적으로 우수하거나 나쁜 프로그램 설계를 장려하는 이유는 무엇입니까? 코드를 테스트하기 어렵게 만들거나 더 쉽게 만들 수 있습니까?

이 질문이 너무 모호하거나 광범위하다면 용서하십시오. 나는 이와 같은 API를 광범위하게 사용했을 때의 잠재적 결과와 그것을 사용할 수있는 다른 방법에 대해 머리를 감싸려고합니다.

편집 :이 패턴의 가장 큰 문제는 API가 종속성 및 객체 커플 링에 대한 "거짓"이며 다음 예제로 설명 할 수 있다는 것입니다.

myObj = new Foo();
myOtherObj = new Bar();
print myOtherObj.someValue; // prints 0
myObj.doSomething();
print myOtherObj.someValue; // prints 1, unexpectedly, because I never indicated that these objects had anything to do with each other

이 예를 구체적으로 또는 일반적인 청취자 패턴에 의문을 가지고 있습니까?
TheLQ

나는 이것이 청취자 패턴보다 넓다고 생각합니다. 리스너 패턴은 ​​잘 정의 된 객체 구조로 특정 객체에 리스너를 등록하여 "정확하게"구현할 수 있습니다. 내 불확실성은 글로벌 메시지 / 이벤트 허브 패턴에 관한 것입니다.
Magnus Wolffelt

답변:


6

나는 그것이 나쁜 프로그래밍을 장려한다고 말하지는 않을 것입니다. 그러나 쉽게 오용 될 수 있습니다.

실제 아이디어는 무엇입니까?
알림 소스는 알림 만합니다. 잠재적 인 관찰 자나 다른 존재의 존재에 대해서는 가정하지 않습니다. 관찰자는 처리하도록 설계된 알림을 등록합니다. 관찰자는 처리 할 수있는 알림에 대한 잠재적 소스 수에 대해 어떤 가정도하지 않습니다.

이것은 소스에 옵저버 또는 옵저버가 소스를 알지 않고도 의존성 주입을 달성하는 방법입니다. 그러나 전체 시스템이 작동하려면 올바른 알림을 위해 올바른 관찰자를 연결해야하며이 시스템은 컴파일 시간을 확인할 수 없기 때문에 오타에도 취약합니다.

물론 가장 큰 위험은 누군가가 이것을 사용하여 1-1 통화에 전 세계적으로 수많은 개체를 사용할 수 있다는 것입니다.


6

비동기 메시징은 확장해야하는 대규모 시스템에 적합한 아키텍처 원칙입니다.

이것과 동등한 Java는 JMS이며 일반적으로 좋은 것으로 간주됩니다 .

실제로 메시지를 서비스하는 코드에서 클라이언트 코드의 분리를 촉진하기 때문입니다. 클라이언트 코드는 메시지를 게시 할 위치 만 알면됩니다. 서비스 코드는 메시지를 어디에서 받을지 알아야합니다. 고객과 서비스는 서로를 알지 못하므로 필요에 따라 서로 독립적으로 변경할 수 있습니다.

메시지 허브의 URI를 쉽게 외부화하여 구성 가능하고 소스 코드에 포함되지 않도록 할 수 있습니다.


4

일반적인 Oberserver Pattern 구현입니다 (또는 리스너 패턴 또는 Subscriber / Publisher 패턴이라고도 함). 이것이 유용한 동작 인 응용 프로그램에서는 구현하기에 좋은 패턴입니다. 솔루션에 값을 추가하지 않으면 패턴을 구현하지 않아야합니다.

귀하의 질문에 따르면 NotificationCenter에 대한 모든 것이 알고 있으며 전 세계가 BAD라는 것에 대해 걱정하는 것 같습니다. 때로는 그렇습니다. 전세계적인 일이 나쁩니다. 그러나 대안을 보자. 두 가지 구성 요소가 있다고 가정 해 봅시다.이 예제에서는 실제로 무엇을하는지 또는 무엇인지 중요하지 않습니다. Component1에는 어떤 방식으로 작동 또는 변경된 일부 데이터가 있습니다. Component2는 Compoent1이 관리하는 유형의 데이터 변경 사항에 대해 알고 싶습니다. Component2가 Component1의 존재에 대해 알아야합니까? 아니면 응용 프로그램의 일부 구성 요소가 관심있는 데이터를 변경했다는 메시지를 Component2 구독 / 청취하는 것이 더 좋습니까? 이제이 예를 들어서 수십 개 이상의 컴포넌트로 곱하면 패턴의 값이 어디에 있는지 알 수 있습니다.

모든 상황에 완벽한 솔루션입니까? 구성 요소 간 통신을 추상화하고 더 느슨한 결합을 제공합니까?


1
위키피디아에서 읽을 때 관찰자 패턴 정의는 전 세계적으로 사용 가능한 이벤트 허브를 포함하지 않는 것으로 보입니다. 이벤트 허브가 관련된 모든 객체의 생성자 / 메서드에 전달 된 경우이 패턴을 좋은 패턴으로 간주합니다. 실제로 글로벌 액세스 포인트이며 그 상태가 불확실합니다.
Magnus Wolffelt

0

이벤트 중심 시스템에 적합하며, 여러 개의 옵저버가 서로를 관찰하는 것보다 우연히 발생할 수 있습니다. 이는 이벤트 처리기를 사용하여 서로 연결할 수있는 이벤트 중심 ActiveX 컨트롤이 있었을 때 VB 시절에 실제로 문제가되었습니다.

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