Чи заохочує схему “Центру сповіщень” хороший чи поганий дизайн програми?


13

Іноді я стикаюся з такими API-стилями стилів-повідомлень, наприклад, NSNotificationCenter Cocoa: 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

Я вважаю, що це ширше, ніж модель слухача. Зразок слухача може бути реалізований "чисто" з чітко визначеною структурою об'єкта та реєстрацією слухачів на конкретних об'єктах. Моя невпевненість полягає в глобальній схемі центру повідомлень / подій.
Магнус Вулффельт

Відповіді:


6

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

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

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

Найбільша небезпека, звичайно, полягає в тому, що хтось скористається цим, щоб зробити тони об'єктів у всьому світі доступними для 1-1 дзвінків.


6

Асинхронний обмін повідомленнями є хорошим архітектурним принципом для великих систем, які повинні масштабуватись

Java-еквівалент цього JMS - це, як правило, хороша річ .

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

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


4

Це типова реалізація шаблону Oberserver (або іноді називається шаблоном слухача або іноді називається шаблоном абонента / видавця). У додатках, де ця поведінка корисна, це вдала модель. Жодна модель не повинна бути реалізована, якщо вона не додає значення рішенню.

З вашого запитання вам здається, що ви стурбовані тим, що все знає про центр сповіщень і що глобальні речі - БАД. Іноді так, глобальні речі погані. Але давайте розглянемо альтернативу. Скажімо, у вас є 2 компоненти, для цього прикладу насправді не важливо, що вони роблять або що вони. Компонент1 має деякі дані, на які діяли або певним чином змінювались. Компонент2 хотів би знати про будь-які зміни в даних типу, якими керує Compoent1. Чи повинен компонент2 знати про існування компонента1? Або було б краще, щоб Component2 підписався / прослухав повідомлення, яке говорить про те, що якийсь компонент десь у додатку змінив деякі дані, які його цікавлять? Тепер візьмемо цей приклад і помножте його на десятки і більше компонентів, і ви зможете побачити, де лежить значення шаблону.

Це ідеальне рішення для кожної ситуації, ні. Чи є абстрактна комунікація між компонентами та забезпечує більш вільну зв'язок, так.


1
Читаючи у wikipedia, визначення шаблону спостерігачів не містить глобально доступного центру подій. Якщо центр подій був переданий в конструктор / метод усіх відповідних об'єктів, я вважав би це гарною схемою. Дійсно, ця глобальна точка доступу та її стан робить мене непевним.
Магнус Вулффельт

0

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

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