Подход данных против подхода ООП - PullRequest
38 голосов
/ 26 апреля 2011

Когда я проектирую свою систему с нуля, я часто сталкиваюсь с дилеммой, должен ли мой объект передавать информацию в другие объекты ИЛИ должны ли объекты извлекать необходимые данные из других объектов.

Есть ли что-то похожее на стандарт в дизайне ООП, в котором я бы предпочел извлечение данных объектами, а не выталкивание данных в объекты?

Может кто-нибудь опытный советовать, является ли один подход лучше другого с долгосрочной точки зрения , или когда структура / структура / диаграмма ООП становится более сложной?

Ответы [ 12 ]

23 голосов
/ 02 мая 2011

Согласно скажите, не спрашивайте , толчок лучше - или больше ОО.Вы не хотите запрашивать у объекта данные, чтобы вы могли что-то сделать, вы хотите, чтобы объект это сделал, потому что он тот, кто знает его данные.

Статья по теме о злых добытчиках

20 голосов
/ 11 апреля 2012

Как указано в других ответах, ни толчок, ни тяга не лучше, но лучше выбрать тот, который наилучшим образом соответствует вашим потребностям дизайна.

Начиная с здесь обсуждается вопрос о том, должна ли модель наблюдателя основываться на толчке или вытягивании:

Кто запускает обновление?

Связь между субъектом и его наблюдателями установлена через метод уведомления, объявленный в интерфейсе наблюдателя. Но это может быть вызвано либо объектом, либо объектом наблюдения. Обычно Метод уведомления запускается субъектом при изменении его состояния. Но иногда, когда обновления происходят часто, последовательные изменения в субъект определит множество ненужных операций обновления в наблюдатель. Чтобы сделать этот процесс более эффективным, наблюдатель может нести ответственность за запуск операции уведомления, когда она считаю необходимым.

Для этого шаблона определяющей характеристикой является частота, с которой изменяются данные, а затем соответствующая скорость, с которой наблюдатели хотят получать эти данные. Если наблюдатели хотят, чтобы данные были медленнее, чем субъект генерирует данные (например, GPS на телефоне, вам не нужно постоянно указывать свое местоположение, только если вы используете его специально), тогда опрос более эффективным. Если наблюдатели хотят, чтобы данные были настолько быстрыми, насколько субъект может их представить (возможный пример - приложение тикера в режиме реального времени), тогда push-уведомления, вероятно, лучше.

19 голосов
/ 18 мая 2015

Я думаю, что в этой дискуссии упущен важный момент о вытягивании и толкании, и он застрял на отдельных примерах и случаях.

Толкание: Преимущество толкания заключается в том, что вызнать свои данные, и вы знаете, что вы нажимаетеНи один компонент не знает (или не должен знать) данные лучше, чем компонент, которому принадлежат данные, что теоретически означает лучшую конструкцию и более надежную систему.

Подтягивание : единственное преимуществоЯ вижу в подходе вытягивания компонент, который точно знает, когда он должен тянуть.Он может инициировать диалог, когда ему нужны данные, и ни один компонент не знает (или не должен знать), когда нужны данные, чем компонент, которому они нужны.

Мой вывод по этому вопросу: , какой бы компонент не былвладеет транзакцией, она инициирует транзакцию .Если вы извлекаете данные из API, очевидно, что клиент API будет владеть транзакцией, поэтому сделаем попытку.Если вы передаете сообщение, то вещатель владеет транзакцией, поэтому он выполняет толчок.

3 голосов
/ 11 апреля 2012

Не должно быть никаких различий в ООП (может быть, я что-то упустил), но подход по принципу вытягивания лучше.

Причина, по которой я это говорю, заключается в последних тенденциях в шаблонах проектирования. Дизайн, управляемый доменом и CQRS , являясь одними из самых выдающихся, они способствуют слабой связи, что очень хорошо.

Объекту должно быть все равно, какой другой объектделает с его данными, это не так сказать, это ответственность.Объект должен только сделать данные доступными, и тогда те, кому нужны данные, должны извлечь / извлечь его из этого объекта.Посмотрите на дизайн, управляемый событиями.

Это делает объект независимым от других объектов и делает его более переносимым (не нужно менять место, куда он толкает, поскольку он будет извлечен).

TL; DR Я бы порекомендовал тянуть за толкание.

ПРИМЕЧАНИЕ: все эти различные шаблоны проектирования не исключают друг друга, но сосуществуют.

2 голосов
/ 17 ноября 2015

назначение. Нажмите (источник)

  • Пункт назначения знает, что и как получить данные из источника
  • Место назначения должно зависеть от источника или
  • else Источник должен реализовывать предоставленный интерфейс ISource и зависеть от провайдера (возможно, это пакет назначения)
  • Метод имеет прямой частный доступ к месту назначения.

источник. Прицепные (назначения)

  • Источник знает, что и как поместить в пункт назначения
  • Источник должен зависеть от пункта назначения, или
  • else Назначение должно реализовывать предоставленный интерфейс IDestination и зависеть от провайдера (может быть пакет Source)
  • Метод имеет прямой частный доступ к источнику.

Выберите свое решение, посмотрев на зависимости, которые вы хотите иметь в своем коде.

Если источник и пункт назначения не могут зависеть от того, что необходимо для предыдущей схемы, то вам нужно, чтобы действие было выполнено внешним методом, который знает (зависит от) как источник, так и пункт назначения. Он имеет только публичный доступ к обоим.

Если вам нужен какой-либо виртуальный ISource для подачи любого IDestination, тогда вам нужны эти интерфейсы, чтобы предоставить все методы, необходимые внешнему методу для выполнения действия.

Если один внешний метод не может выполнить действие на каком-либо ISource и каком-либо IDestination, тогда вы можете захотеть взглянуть на шаблон Visitor, класс Visitor, выполняющий все конкретные действия для определенных Source1 и SourceX Destination1 и DestinationY.

1 голос
/ 26 ноября 2013

Во-первых, общее правило ясно: объекты данные и поведение .Это поощряет меньше получателей и тем меньше тянет , предоставляя методы, которые делают что-то с внутренними данными.

Один "толкать лучше" (в принятом ответе) можетне работает, так как push-операция в некотором классе может потребовать нового нажатия на объект push.Вместо этого лучше всего добавлять операцию push, где она лучше всего подходит для абстракции.Это может даже привести к появлению нового, более абстрактного класса / состава классов (см. Эвристика объектно-ориентированного проектирования , Riel, 1996, стр. 37 и далее).

1 голос
/ 11 апреля 2012

Слово push / pull является относительным.Там будет пушер, у которого есть данные, и пуллер, которому нужны данные.Если мы на самом деле храним данные в нейтральном месте, а не внутри push-er / pull-er, возникает много возможностей, которые удовлетворяют данной проблеме в одно время.данные в его удобстве.Множество шаблонов проектирования, MVC, Observer, Command и т. Д. Используются для обработки сценария.

1 голос
/ 10 апреля 2012

Обычно «извлечение данных» означает, что вы делаете вызов ajax и выполняете обратный вызов при его успешном ответе. Это неплохо, но это может быть слишком интенсивно, если вы проверяете обновления данных и, таким образом, делаете это с интервалом.

Но в контексте онлайнового веб-приложения альтернативой этому является push с длительным опросом. Поскольку длинный опрос не сильно отличается от первого метода, я предлагаю вам сделать следующее:

Создайте метод длинного опроса, который извлекает данные из полуоткрытой конечной точки push-url (также называемой веб-сервисом для pubsub), а затем обновляет все, что необходимо обновить, с помощью шаблона проектирования издатель-подписчик в вашем клиенте. Таким образом, ваши обновления будут более отделены от источника данных.

Вот статья, написанная IBM на эту тему. http://www.ibm.com/developerworks/library/specification/ws-pubsub/

1 голос
/ 29 апреля 2011

Ответ зависит от ваших архитектурных целей, другими словами, нет общего решения.

В архитектуре клиент-сервер у вас, скорее всего, будет многоуровневая система на бэкэнде, в которой объекты извлекают состояние из других объектов. Это означает, что только определенные «службы» в конечном итоге обновят состояние объекта. Пример: создание нового объекта, обновление поля объекта и т. Д. (Например, добавление нового элемента заказа в общий заказ).

В настольном монолитном приложении оно может быть совершенно другим. Скорее всего, вы используете вариации «Модель-Вид-Контроллер», шаблоны наблюдателей и т. Д. В этом случае вы нажимаете кнопку «Информация», например, в пользовательский интерфейс.

0 голосов
/ 11 апреля 2012

С моей точки зрения ... Как разработчик настольных приложений, использующих mvc, существует тонкая связь, при которой вы отправляете данные, когда они доступны для объектов модели, а затем основаны на логике в модели (таймеры / асинхронные события / уведомления), а затемданные передаются в контроллеры и, в свою очередь, в представление ... Взаимодействия с пользовательским интерфейсом могут идти в любом направлении, в зависимости от предпочтений, они могут запускать сообщение обновления или обновления, которое сообщает контроллеру, что он должен что-то сделать, или может специальнопроталкивать данные в контроллер и часто по очереди модель.

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

...