2016-02-20 1 views
1

Допустим, вы создали два объекта: objectA и objecB. Если Objecta необходимо отправить сообщение на objectB это должно происходить так:Когда объект A хочет отправить сообщение объекту B, где должен жить метод?

objectA.theMessage(objectB) 

или как это:

objectB.theMessage(objectA) 

Более конкретный пример:

Publisher p; 
Subscriber s; 

// way 1 
p.addSubscriber(s); 

// way 2 
s.subscribeTo(p); 

Как вы можете видеть, семантика обоих messeges (функций) одинакова, а именно вопрос о том, где должна функционировать функция.

Есть жесткое и быстрое правило, в котором говорится, что нужно делать? Или есть общее руководство, которое поможет вам определить, какой из них лучше? Или это дело в отдельности и нет общего руководства? Если да, не могли бы вы объяснить, когда я буду использовать их каждый. Можете ли вы представить себе какие-либо потенциальные преимущества/недостатки каждого?

Большое спасибо за ваше время и знания!

+1

Вы получите больше внимания на этот вопрос, если бы вы добавили тег, специфичный для языка, но то, что вы ищете, называется шаблоном Observer. –

+0

Благодарим вас за советы по добавлению языкового тега! :) Я знаю о шаблоне наблюдателя, вот почему я использовал пример издателя/подписчика :) ха-ха. О чем я спрашиваю: существует ли общее правило (не ограничиваясь шаблоном наблюдателя) о том, где должны жить сообщения? В каком объекте они должны жить? :) – MeLikeyCode

ответ

2

Разница заключается в том, предпочитаете ли вы толчок или тянущий рисунок. Какой из них лучше всего подходит, зависит от приложения. «Push» в основном означает, что A отправляет B сообщение, тогда как «pull» означает, что B получает сообщение от A.

Как уже говорилось, общего правила нет, но часто можно ответить на вопрос здравым смыслом. Рассмотрим пример: сегодня утром мы с семьей позавтракали. Раньше мне приходилось ездить в пекарню, чтобы получить хлебные булочки (это в Германии, нам нравится наш Бретчен). С другой стороны, газета, которую я читал за завтраком, была доставлена ​​поставщиком бумаги. Эта настройка подходит: мне нужны хлебные булочки, поэтому я сделал некоторую работу, чтобы получить их, но я, вероятно, был бы ленив, чтобы пойти и купить газету (если только это не может быть получено у пекаря). С другой стороны, если бы хлебные булочки были доставлены, а газета не была бы, у меня были бы более дорогие булочки и ни одна газета. Глупый пример.

Итак, что это значит для вашего дизайна? Тот, кто обязательно нуждается в сообщении, отправлен с A на B, запускает его. По моему опыту, это часто приемник, поэтому шаблон вытаскивания часто является первым выбором (также он позволяет более легко оценить ленивая оценка - только получите сообщение, когда это действительно необходимо). Но, как сказано, это действительно зависит от приложения. Сделайте свой выбор :-)

+0

Я думал, что метод push/pull использовался, когда один объект хочет знать, когда что-то случилось с другим объектом? Например, если у нас есть объект Timer и объект Person, человек хочет знать, запущен ли таймер, push предложит Таймер TELLS Person, когда он запустится, где, когда pull будет предлагать Person ASK, таймер «у вас есть началось? периодически. В примере, который я использовал в моем вопросе (подписчик, подписывающийся на издателя), который вы бы предпочли сделать: publisher.addSubscriber (подписчик) или подписчик.subscribeTo (издатель)? – MeLikeyCode

+0

... продолжение ... Где должна быть ответственность за добавление подписчика в puslisher?Я «чувствую», как будто это должно быть в издателе, однако я также «чувствую», как если бы я позволял клиентам делать это, это придавало бы им большую гибкость. Но тогда я должен был бы убедиться, что код находится только в одном классе (другое просто делегирование). В этом случае вам понадобится один из классов для доступа к частным (хе-хе) другого класса, что уменьшает инкапсуляцию? Таким образом, добавленная гибкость для клиента стоит более сильная связь и сокращение инкапсуляции? – MeLikeyCode

+1

@MeLikeyCode: ваши мысли относительно push/pull просто равны тому, что я написал в ответе. Короче говоря: «Push»: 'A' нажимает на' B'. «Pull»: 'B' тянет от' A'. Обычный подход к проблеме подписки - это, как вы сказали: 'A' предлагает' 'subscribeWithMe'', а' B' должен называть это с собой ... но обратите внимание, что это соответствует шаблону push. Используя шаблон pull, 'A' в принципе не обязательно должен знать' B' вообще, но, конечно, 'B' должен знать' A' (т.е. быть построенным с помощью 'A' или предоставить метод' pullFrom (A *) и т. Д.). Если у вас нет фиксированного потока информации, вы не получаете его/действие пользователя wo. – davidhigh

Смежные вопросы