Объекты, которые отправляют сами - хорошая идея? - PullRequest
9 голосов
/ 10 сентября 2010

Где вы рисуете линию при перемещении функций, которые работают с данными, в класс, который содержит эти данные?Например, представьте, что у вас есть простой класс, в котором хранится описание погоды с переменными для температуры, влажности, скорости и направления ветра, а также время, в которое было произведено измерение.Теперь представьте, что у вас есть объект этого класса, и вы хотите передать его кому-то другому - другому процессу, другой машине, что угодно.Поместите ли вы код для передачи объекта в сам объект - например, добавив метод Send (destination-type) в простой класс данных?Или вы храните такую ​​функцию в отдельных классах, которые могут отправлять и получать что-либо через носитель - будь то сетевое взаимодействие, файловый ввод-вывод, обмен данными между процессами или что-то подобное?

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

Это кажется очевидным для меня, но я продолжаю наблюдать, как разработчики помещают методы Send () в свои классы.Они даже говорят message классам самим Send (), что мне кажется крайне нелогичным;если я напишу письмо на листе бумаги, я не скажу, чтобы бумага отправлялась сама.Я завернул письмо в конверт и вручил его почтальону, потому что у него есть фургон и карта.Что думают люди?

Ответы [ 4 ]

8 голосов
/ 10 сентября 2010

Логика имеет отношение к самому элементу полезной нагрузки: какова скорость ветра сейчас?

В интерпретации этих данных есть логика: можем ли мы пристыковать этот корабль сейчас?

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

Тогда фактический материал сети.

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

6 голосов
/ 10 сентября 2010

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

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

Однако я не хочу, чтобы это приводило к нарушению границ между уровнями моего приложения. Я не хочу, чтобы бизнес-объект знал, как представлять себя в виде HTML - это проблема презентации. Так что в этом случае я бы сказал, что класс должен знать, как представлять себя каким-то каноническим образом, но он не должен знать о сетевых вещах. Фактическая функция отправки должна принадлежать услуге.

5 голосов
/ 10 сентября 2010

В своей карьере я несколько раз обсуждал подобные вопросы о дизайне. Прямо сейчас я нахожусь там, где вы, кажется, в основном потому, что я делаю много SOA в моей нынешней жизни, и я заканчиваю тем, что пишу МНОГО предложений, которые существуют только для сериализации в различные внешние форматы проводов, в основном с использованием XML и JSON.

Когда вы переходите в мир «сервисов», классы часто являются просто представлениями данных, которые отправляются туда и обратно. Поэтому я обычно делю свои классы на два логических блока: «классы, которые содержат данные» и «классы, которые делают вещи». Я не знаю, делаю ли я один такого рода вещи, но я на этом и остановился.

2 голосов
/ 10 сентября 2010

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

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

Поэтому возникает вопрос: когда объект может манипулировать своими собственными данными и когда мне нужно разделить их?out.

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

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

Например, если методы String, такие как Split и Join и Substring, было нелегко найти вСтроковый класс и вместо этого где-нибудь еще, например, как гипотетический класс Parse, вполне вероятно, что прежде чем я нашел этот гипотетический класс Parse, я написал бы несколько дрянных версий этих методов.Пример из реальной жизни это когда люди пишут методы, идентичные методам в классе Math, потому что они не знают об этом.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...