Здравствуйте, Ziaw, Вы писали:
Z>Здравствуйте, gandjustas, Вы писали:
G>>Общая проблема состоит в том, что жирная модель (она же domain model) в многозвенном приложении сосет как пылесос.
Z>Тем, что требует DTO для передачи данных?
Не только.
Z>Я на досуге подумал и пришел к такому выводу. Различие между тонкой и жирной моделью лишь в способе получения DTO.
Различий гораздо больше.
Пример — нужно получить список заказов с адресом клиента и фамилией менеджера, отвественного за заказ.
В жирной модели надо загрузить список заказов, для каждого заказа надо загрузить полный объект менеджера и клиента.
Z>То, что называется тонком моделю по сути моделью не является, это DTO, моделью для которых служит БД.
Это бред воспаленного сознания.
ER-модели (модели данных) начали применяться гораздо раньше, чем ООП. Стройная модель — как раз отражение модели данных в программе.
Причеем между моделью данных и схемой хранения может быть достаточно нетривиальынй маппинг.
Z>Поэтому зачастую с тонкой моделью легко уживается логика в БД (логика в модели).
Смысл этой фразы для меня остался загадкой.
Z>В жирной модели между БД и приложением появляется еще один слой — модель предметной области, которая реально является моделью, которую разработать не проще чем модель физического процесса и оправдывает она себя лишь на каком-то пороге сложности предметной области.
Практика показывает обратное. На каком-то пороге сложности domain model перестает оправдывать себя.
Z>У нее полно минусов, она очень неоптимально использует СУБД, нам требуется трекать изменения сделанные клиентом, чтобы проапдейтить эту модель. Но, грамотно построенная, она не позволяет нарушить ни одного бизнес правила и дает максимально полный интерфейс для работы над собой.
Это за счет чего достигается? Магией чтоли?
И что вообще означает "не позволяет нарушить ни одного бизнес правила", если программа чего-то такого допускает, то это бага.
Кстати, а что означает "дает максимально полный интерфейс для работы над собой"?
Z>Вобщем Фаулер и Эванс не пропагандируют overarchitect, они лишь рассказыват как подняться на еще одну ступеньку в борьбе со сложностью продукта.
Угу, борьба со сложностью способом увеличения сложности — замечательно.
Z>Любой такой шаг не бесплатен и любой оправдан лишь в тех случаях, когда без него гораздо хуже.
Пример такого случая будет?
Re[4]: Архитектура приложения с несколькими клиентами и одни
Здравствуйте, Ocenochka, Вы писали:
O>Здравствуйте, Ziaw, Вы писали:
G>>>Общая проблема состоит в том, что жирная модель (она же domain model) в многозвенном приложении сосет как пылесос. Z>>Тем, что требует DTO для передачи данных?
O> Думаю в большинстве случаев можно передавать объекты domain model. Логика не должна, на мой взгляд, в них содержаться.
Тогда это будет не domain model
Re[4]: Архитектура приложения с несколькими клиентами и одни
Здравствуйте, gandjustas, Вы писали:
G>>>Общая проблема состоит в том, что жирная модель (она же domain model) в многозвенном приложении сосет как пылесос. O>>Прошу кратко аргументировать. Или дать ссылку на развернутое объяснение желательно с минимумом терминологии (она у каждого своя) и с примерами. G>Описанные проблемы обоих решений — уже аргумент.
Проблемы первого решения для меня еще не являются агрументом для отказа от domain model.
O>>>> — не ясно как разруливать конфликт при серии изменений в которых только одно изменение было неудачно — пользователь будет O>>>> очень не рад вспоминать что он делал и переделывать. G>>>Я скажу по секрету, что ты сможешь нарваться на конфликты изменений, которые не будут отловлены твоим механизмом. O>> Можно на маленьком примере пояснить? Как могут конфликты не быть отловлены, если каждая сущность имеет версию? G>Спокойно.
Интересно, что в моем предложении заставило вас считать, что я не спокоен?
G>Версия не будет проверяться если не было никаких изменений. Если у вас корректность данных зависит от совокупности сущностей и один клиент меняет одну, а другой — другую, то такой конфликт не может быть отловлен.
Если один клиент меняет одну сущность, а другой другую то в момент применения изменений это выясниться блягодаря наличию версии объекта.
O>> А почему нельзя на клиентов выгружать "оторваные" данные и пытаться их апдейтить с учетом версии? Без наличия обратной связи, т.е. чтобы на клиентах разрешались неактуальные данные пока не потребуется внести изменения. G>А в какой момент мерджить изменения?
Да, при нажатии на Save, однако, мержить не выйдет — только потеря изменений, обновление и последующая попытка изменения. Ну может получится смержить, но это отдельная проблема, которую пока можно не рассматривать.
G>Наверное при нажатии save, но в таком случае и передавать на сервер не надо.
Как не надо? А как об изменении смогут узнать другие клиенты?
G>Если не save, то постоянная обратная связь со всеми вытекающими.
Обратная связь относится к решению N2. Как организовать такое решение я пока что не услышал. Выгружать на каждого клиента датасеты и городить соответственную инфраструктуру, на мой взгляд, много сложнее, тем более, что это все равно не спасет от проверки версий объектов, не говоря уже о проблемах, когда клиенты теряют связь с сервером.
O>>>>Интересно какие в этом решении еще могут быть проблемы и как с ними бороться. Тестовый прототип уже пишу, но все равно хочу знать мнение практикующей общественности. G>>>В таком решении ты найдешь тысячи граблей, с которыми будешь долго бороться. O>> Пока не вижу у нас единого взгляда на это решение, учитывая заданные мне вопросы. G>А ты подробнее распиши задачу и покажи свои наработки.
Задача занимает сейчас около 100 стр. при этом я не могу понять что даст раскрытие ньюансов конкретной предметной области. Премер я уже приводил. Наработки еще не закончены, однако есть четкое представление архитектуры.
G>Создавать сферическую архитектуру в вакууме не получится.
Однако, глядя на ваши ответы, я считаю, что у вас это вполне получается Без обид. Просто я не вижу у вас понимания решения N1. То, что вы пробовали городить dataset'ы — это я уже выяснил и то что опыта с orm и domain model не имели то же выяснил
O>>>> Воообще, интересуют любые решения практикующих разработчиков, а так же мнения относительно адекватности двух приведенных мною решений. Адекватность прошу оценивать по времени написания, отладки и поддержки. G>>>Оба неадекваты на 99% O>> Предлагайте! G>Сделать кнопку Save, по которой сохранять изменения. G>Далее 3 варианта: G>1)Локальная реплика БД, которая хранит измененные данные (dataset или SQL CE) и периодическая синхронизация с сервером (передача changeset датасета или Sync Services для SQL CE)
В задаче сказано, что БД — одна.
G>2)Написать кучу сервисов и DTO
Это зачем и к чему?
G>3)Воспользоваться EF\Linq2SQL+ADO.NET Data Services
Каким образом?
Есть четкая задача, которую я обозначил дважды, повторю еще раз: есть два клиента, работающих с общей БД. Как реализовать их работу при отсутствии коллизий?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Люблю ставить оценки.
Re[5]: Архитектура приложения с несколькими клиентами и одни
Здравствуйте, gandjustas, Вы писали:
O>> Думаю в большинстве случаев можно передавать объекты domain model. Логика не должна, на мой взгляд, в них содержаться. G>Тогда это будет не domain model
Жду определения
Вы же сами называли это тонкой domain model.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Люблю ставить оценки.
Re[6]: Архитектура приложения с несколькими клиентами и одни
Здравствуйте, Ocenochka, Вы писали:
O>Здравствуйте, gandjustas, Вы писали:
O>>> Думаю в большинстве случаев можно передавать объекты domain model. Логика не должна, на мой взгляд, в них содержаться. G>>Тогда это будет не domain model
O> Жду определения O> Вы же сами называли это тонкой domain model.
Обычно под понятием domain model понимают rich. Потому что фаулер в своей книге именно так и описал.
Re: Архитектура приложения с несколькими клиентами и одним с
Здравствуйте, Ocenochka, Вы писали:
O>Уважаемые представители коллективного разума, помогите пожалуйста разобраться.
O> Задача: O> Есть проект, в который входит несколько клиентских приложений (WinForms) для работы с одними и теми же данными — общая БД. O> Сейчас принято решение иметь так же одно серверное приложение содержащее либо только слой доступа к данным, либо еще всю или часть бизнес-логики. В сервере в качестве DAL будет использоваться NHibernate с включенным кэшем. O> (Решение о централизованном сервере может быть изменено в случае наличия удовлетворительных аргументов.) O> Общая проблема: O> Наличие коллизий при работе разных клиентов с одними и теми же данными. Т.е., например, оба клиента получили объект, изменили его и отправили обновлять на сервер — в результате произойдет только одно изменение.
O> Решение N1:
O> Решение N2:
O> Воообще, интересуют любые решения практикующих разработчиков, а так же мнения относительно адекватности двух приведенных мною решений. Адекватность прошу оценивать по времени написания, отладки и поддержки.
O>зы Спасибо за внимание!
Добрый день.
Хочу попробовать помочь, высказав свои соображения.
Прежде всего, вариант N2 следует отмести как нереализуемый -- уж очень много всяких косяков там вылезает: начиная от проблем с проксями NHibernate и заканчивая сбоями сети. Кроме того, работа по сети в таком случае выльется в безобразные тормоза на клиенте.
Итак, остается вариант №1, которым обычно и пользуются при написании 3хзвенок.
Чтобы претворить его в жизнь, нужно:
1) Определиться с генератором DTO: будет он или вы сами будете гонять отсоединенные объекты (DTO можно готовить и руками, но лучше взять что-либо типа otis lib);
2) Кнопка Save в вашем случае -- отличное решение; нужно только определиться с сеансами редактирования (т.е. где эти кнопки будут находиться и каковы будут участки, работа на которых идет от сохранения до сохранения;
3) Определиться с тем, как вы будете решать конфликты одновременного обновления: пессимистический вариант и оптимистический, соотственно.
В случае пессимистического вы не допускаете конфликтов -- при помощи транзакций БД(хардкор, но иногда допустим или на уровне бизнес-транзакций (т.н. conversation), помечая и блокируя бизнес-объекты , находящиеся в редактировании;
В случае оптимистического варианта вы решаете разруливать конфликты одновременного обновления по факту обнаружения таких конфликтов. Вариантов здесь а)затирать старые изменения (игнорируем конфликт) б) не давать затирать при помощи проверки версии (NHibernate вам в помощь) и просить пользователя внести вторично правку в устаревшие данные в) реализовать стратегию merge данных, если данные могут быть объединены без логического конфликта
Ничего не мешает сочетать эти варианты, согласуясь с другими критериями. Да, и ответ на ваш вопрос -- NHibernate сам умеет поддерживать версии объекта, так что коллизий не будет; если вам интересно, я напишу следующим сообщением, почему описанная вами ситуация не случится.
4) Определитесь со стратегией кеша и провайдером кеша (не все из них поддерживают блокировку объектов!). Со своей стороны могу порекомендовать SharedCache.net, ибо пробовал, понравилось; memcached не пробовал, но буду в след. проекте;
5) Определиться со стратегией выработки Id(PK) для бизнес-объектов -- некоторые, например, identity, плохо совместимы с NHibernate 2nd level cache.
Если заинтересовало, пишите, продолжим обсуждение трудностей и подводных камней.
Re[5]: Архитектура приложения с несколькими клиентами и одни
G>>Наверное при нажатии save, но в таком случае и передавать на сервер не надо. O> Как не надо? А как об изменении смогут узнать другие клиенты?
Сам же написал что без обратной связи. Тогда зачем до save куда-то что-то передавать?
O>>>>>Интересно какие в этом решении еще могут быть проблемы и как с ними бороться. Тестовый прототип уже пишу, но все равно хочу знать мнение практикующей общественности. G>>>>В таком решении ты найдешь тысячи граблей, с которыми будешь долго бороться. O>>> Пока не вижу у нас единого взгляда на это решение, учитывая заданные мне вопросы. G>>А ты подробнее распиши задачу и покажи свои наработки.
O> Задача занимает сейчас около 100 стр. при этом я не могу понять что даст раскрытие ньюансов конкретной предметной области. Премер я уже приводил. Наработки еще не закончены, однако есть четкое представление архитектуры.
Может дать очень много потому что единственное что сейчас видят люди на форуме — это твое трактование предметной области.
G>>Создавать сферическую архитектуру в вакууме не получится.
O> Однако, глядя на ваши ответы, я считаю, что у вас это вполне получается Без обид. O>Просто я не вижу у вас понимания решения N1.
Это у тебя нету понимания решения N1, я такие решения в разных видах уже делал.
O>То, что вы пробовали городить dataset'ы — это я уже выяснил
Мимо. Как раз решения с dataset я предпочитаю не городить, я один раз начал такое делать и быстро отказался.
O>и то что опыта с orm и domain model не имели то же выяснил
Совсем мимо. С orm работаю постоянно и даже свой писал.
Хреновый из тебя телепат.
O>>>>> Воообще, интересуют любые решения практикующих разработчиков, а так же мнения относительно адекватности двух приведенных мною решений. Адекватность прошу оценивать по времени написания, отладки и поддержки. G>>>>Оба неадекваты на 99% O>>> Предлагайте! G>>Сделать кнопку Save, по которой сохранять изменения. G>>Далее 3 варианта: G>>1)Локальная реплика БД, которая хранит измененные данные (dataset или SQL CE) и периодическая синхронизация с сервером (передача changeset датасета или Sync Services для SQL CE) O> В задаче сказано, что БД — одна.
И что? SQL CE — несколько dll и больше ничего не надо
G>>2)Написать кучу сервисов и DTO O> Это зачем и к чему?
Ко всему. Если клиент не толстый, то лучше увеличить гранулярность обращения к серверу. Для этого потребуется метод сервиса и вероятнее всего DTO.
G>>3)Воспользоваться EF\Linq2SQL+ADO.NET Data Services O> Каким образом?
Создть модель в EF дизайнере, создать сервис ADO.NET, сделать клиент.
O> Есть четкая задача, которую я обозначил дважды, повторю еще раз: есть два клиента, работающих с общей БД. Как реализовать их работу при отсутствии коллизий?
Наверное при наличии коллизий. Варианта как всегда два:
1)пессимистичная блокировка — когда данные могут меняться только одним клиентом в один момент времени.
2)оптимистичная блокировка, когда оба редактируют данные, если при попытке сорхнанить версии не сопадают — исправить конфликт и попытаться еще раз.
Оптимистичная блокировка на самом деле блокировкой не является, несмотря на назание, и в некоторых случаях не работает.
Проверка версии происходит только при явном сохранении (кнопка save), причем проверяется средствами БД.
Re[3]: Архитектура приложения с несколькими клиентами и одни
Здравствуйте, Ocenochka, Вы писали:
O>Не очень понимаю как отслеживать изменения. Допустим на клиенте грид с коллекцией объектов. При редактировании в отдельную коллекцию складывать отредактированные объекты? А как порядок редактирования учитывать?
Вы видимо невнимательно прочитали тему. Либо реализовывать флаг IsDirty в самом бизнес-объекте (базовом классе), либо использовать Wrapper, который будет отслеживать изменения обертываемого объекта и реализовывать флаг IsDirty. Если нужно учитывать порядок редактирования — это отдельная задача, но лично мне никогда не нужно было учитывать порядок редактирования. Вы уверены что вы заранее не усложняете задачу зачем-то?
O>>> — возникает необходимость хранить список изменений или передавать все потенциально измененные объекты; MC>>Смотрите тему http://rsdn.ru/forum/design/3367411.flat.aspx
O>Прочитал. Понял не много и легче не стало.
Может стоит еще раз внимательно прочитать? Я серьезно.
O>Врапперы над сущностями и их коллекциями — это круто. Не совсем представляю как это будет в случае с несколькими клиентами.
Видимо у каждого клиента будет своя коллекция обернутых объектов.
O>DataSet то же не хотелось бы, не то, чтобы я сильно религиозен, но мозги придется перекраивать сновательно.
В принципе датасеты вариант, но лично мне кажется что они провоцируют дублирование логики, а так же вынос логики в presentation. К тому же нетипизированные датасеты неудобны отсутствием типизации, а типизированные датасеты дают мало контроля, т.к. все генерируется и перегенерируется автоматически.
O>А последовательность изменений не учитывать? Если пятая операция из 10 не прошла, то, на мой взгляд, логично откатить все 10. Соответственно, пользователю прдется переделывать все 10.
Ну это зависит от задачи. Если мы принимаем 10 заказов от разных клиентов (через веб-сервис к примеру) и принялись только 5, после чего возникла ошибка — то откатывать все не нужно, просто запросить те которые не принялись и попытаться их сохранить. Если же действия должны быть "атомарными", то да, откатываем все 10. Но видимо у нас с вами тут какое-то недопонимание, потому как я не понимаю, почему пользователю придется переделывать все 10? К примеру пользователь открывает форму с разными полями для редактирования и гридом, что-то там изменяет и жмет сохранить. Если где-то косяк (к примеру ошибка валидации или ваша любимая коллизия), то пользователю просто сообщится о конкретной ошибке ("Product price can not exceed $100000"), на форме же останутся изменения сделанные пользователем. Пользователь исправляет что нужно и жмет Сохранить еще раз.
Если же вы про облом операции именно по причине коллизии, то тут надо сначала знать, что должно происходить в случае коллизии? Может просто молча должны записаться изменения пользователя (на мой взгляд зачастую это вполне допустимо), или же надо сообщить пользователю о том что в БД уже етсь измененная версия объекта и спросить хочет ли он ее перезаписать? Или же надо перечитать (или просто отдельно показать) измененный объект из БД? Или надо все перечитать? Это вы должны сначала вместе с экспертами предметной области решить как должна вести себя система.
O>>> б) либо на каждое действие пользователя включать курсор "песочные часы" и отправлять изменения на сервер — в принципе, O>>> не вижу проблем, но почему-то не часто его встречаю (а может реже замечаю) — если есть проблемы, хотелось бы их узнать. MC>>Это просто неправильно так делать.
O>Не правильно делать категоричные заявления без аргументов Ясно, что производительность и отзывчивость могут пострадать, если клиентов будет много, а сервер далеко, но есть подозрение, что дело не в этом.
И в этом тоже. Вы вообще искренне считаете что нормально отправлять изменения и сохранять их на сервере по каждому чиху пользователя? А если он решит отменить изменения?
Re[11]: Архитектура приложения с несколькими клиентами и одн
Здравствуйте, Ocenochka
O> А как можно некорректно изменить данные, которые имеют версию? Два лока сделать одновременно ведь не удасться даже теоретически, на сколько я понимаю.
А вот это очень распространённое заблуждение — верить что программа ценна сама по себе, и не потребуется интеграция с другими системами. Данные у вас лежат в СУБД — любой запрос может помацать их несмотря ни на какие псевдоблокировки. Впрочем это слегка другой вопрос, просто не надейтесь что мой вариант == панацея от всех бед
P.S. Вариант с резервированием рулит когда у вас ресурсов чуть меньше чем клиентов. Если клиентов стабильно толпа, а ресурс используется ограниченное время (не ваш случай) то оптимистические блокировки или "last wins" пожалуй подойдёт лучше.
Re[4]: Архитектура приложения с несколькими клиентами и одни
Здравствуйте, gandjustas, Вы писали:
Z>>Я на досуге подумал и пришел к такому выводу. Различие между тонкой и жирной моделью лишь в способе получения DTO. G>Различий гораздо больше. G>Пример — нужно получить список заказов с адресом клиента и фамилией менеджера, отвественного за заказ. G>В жирной модели надо загрузить список заказов, для каждого заказа надо загрузить полный объект менеджера и клиента.
Обе модели допускают оптимизацию подобных сценариев. Про непотимальныю работу с БД в рич модели by default я уже писал.
G>Это бред воспаленного сознания.
Культура общения для тебя не главное, как я понял. Если диалог не интересен — продолжай в том же духе, я пойму и забью на него.
G>ER-модели (модели данных) начали применяться гораздо раньше, чем ООП. Стройная модель — как раз отражение модели данных в программе. G>Причеем между моделью данных и схемой хранения может быть достаточно нетривиальынй маппинг.
Обе модели отражают данные, обе могут делать это нетривиальными маппингами, что сказать-то хотел? Нетривиальный маппинг в тощей модели, скорее вреден, так как способствует persistance ignorance, т.о. лишая тощую модель одного из главных достоинств.
Z>>Поэтому зачастую с тонкой моделью легко уживается логика в БД (логика в модели). G>Смысл этой фразы для меня остался загадкой.
С тощей моделью логика в БД уживается лучше, это логично ложится в концепцию БД==модель.
G>Практика показывает обратное. На каком-то пороге сложности domain model перестает оправдывать себя.
Т.е. у тебя был случай, когда изза возрастающей сложности пришлось отказаться от DDD? Или какая практика?
Z>>У нее полно минусов, она очень неоптимально использует СУБД, нам требуется трекать изменения сделанные клиентом, чтобы проапдейтить эту модель. Но, грамотно построенная, она не позволяет нарушить ни одного бизнес правила и дает максимально полный интерфейс для работы над собой. G>Это за счет чего достигается? Магией чтоли? G>И что вообще означает "не позволяет нарушить ни одного бизнес правила", если программа чего-то такого допускает, то это бага.
Различие между программой и моделью не видно? Рич модель не позволяет, а с тонкой можно проделать все что угодно в коде бизнес процессов.
G>Кстати, а что означает "дает максимально полный интерфейс для работы над собой"?
В обеих моделях есть некое ядро, работая с которым нарушить логику невозможно. Интерфейс работы с этим ядром в жирной модели выглядит более богатым, а код самого ядра более компактным. Соответственно проще его верификация.
Z>>Любой такой шаг не бесплатен и любой оправдан лишь в тех случаях, когда без него гораздо хуже. G>Пример такого случая будет?
Не будет, мне пока хватает тощей, хотя рич модель я проектировал тоже, не сказал бы, что она доставляла мне проблемы своим существованием. Даже если бы такой пример у меня был, его описание потребовало бы за сотню страниц текста, который ты все равно не стал бы читать. Но я убежден, что такие сценарии существуют.
... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
Re[5]: Архитектура приложения с несколькими клиентами и одни
Здравствуйте, Ziaw, Вы писали:
G>>ER-модели (модели данных) начали применяться гораздо раньше, чем ООП. Стройная модель — как раз отражение модели данных в программе. G>>Причеем между моделью данных и схемой хранения может быть достаточно нетривиальынй маппинг.
Z>Обе модели отражают данные, обе могут делать это нетривиальными маппингами, что сказать-то хотел? Нетривиальный маппинг в тощей модели, скорее вреден, так как способствует persistance ignorance, т.о. лишая тощую модель одного из главных достоинств.
И почему же вреден? Примеры будут?
Z>>>Поэтому зачастую с тонкой моделью легко уживается логика в БД (логика в модели). G>>Смысл этой фразы для меня остался загадкой. Z>С тощей моделью логика в БД уживается лучше, это логично ложится в концепцию БД==модель.
Это ты сам придумал.
G>>Практика показывает обратное. На каком-то пороге сложности domain model перестает оправдывать себя. Z>Т.е. у тебя был случай, когда изза возрастающей сложности пришлось отказаться от DDD? Или какая практика?
Был. Я узнав про DDD попытался написать прогу в чисто dddшном. К концу разработки код оброс обилием неDDDшных конструкций, от самого DDD осталось мало. При этом на началном этапе я очень много времени потратил на поддержку именно DDD.
Z>>>У нее полно минусов, она очень неоптимально использует СУБД, нам требуется трекать изменения сделанные клиентом, чтобы проапдейтить эту модель. Но, грамотно построенная, она не позволяет нарушить ни одного бизнес правила и дает максимально полный интерфейс для работы над собой. G>>Это за счет чего достигается? Магией чтоли? G>>И что вообще означает "не позволяет нарушить ни одного бизнес правила", если программа чего-то такого допускает, то это бага. Z>Различие между программой и моделью не видно?
Модель (елси мы говорим не об артефакте анализа) — часть программы.
Z>Рич модель не позволяет, а с тонкой можно проделать все что угодно в коде бизнес процессов.
И что?
G>>Кстати, а что означает "дает максимально полный интерфейс для работы над собой"? Z>В обеих моделях есть некое ядро, работая с которым нарушить логику невозможно. Интерфейс работы с этим ядром в жирной модели выглядит более богатым, а код самого ядра более компактным. Соответственно проще его верификация.
Не надо ударяться в философию.
В стройной модели есть данные и есть методы работы с ними. Никаких "ядер" "интерфейсов" и прочей мути.
Если есть пример, показывающий обратное — можешь привести.
Z>>>Любой такой шаг не бесплатен и любой оправдан лишь в тех случаях, когда без него гораздо хуже. G>>Пример такого случая будет? Z>Не будет, мне пока хватает тощей, хотя рич модель я проектировал тоже, не сказал бы, что она доставляла мне проблемы своим существованием. Даже если бы такой пример у меня был, его описание потребовало бы за сотню страниц текста, который ты все равно не стал бы читать. Но я убежден, что такие сценарии существуют.
Слепая вера — самое страшное в программировании.
Re[6]: Архитектура приложения с несколькими клиентами и одни
Здравствуйте, gandjustas, Вы писали:
Z>>Обе модели отражают данные, обе могут делать это нетривиальными маппингами, что сказать-то хотел? Нетривиальный маппинг в тощей модели, скорее вреден, так как способствует persistance ignorance, т.о. лишая тощую модель одного из главных достоинств. G>И почему же вреден? Примеры будут?
Это обсуждалось на данном форуме тыщу раз. Воспользуйся поиском, пересказывать лень.
Z>>С тощей моделью логика в БД уживается лучше, это логично ложится в концепцию БД==модель. G>Это ты сам придумал.
Что лучше уживается или что логично ложится?
G>Я узнав про DDD попытался написать прогу в чисто dddшном. К концу разработки код оброс обилием неDDDшных конструкций, от самого DDD осталось мало. При этом на началном этапе я очень много времени потратил на поддержку именно DDD.
Примеры неDDDшных конструкций в студию.
Z>>Различие между программой и моделью не видно? G>Модель (елси мы говорим не об артефакте анализа) — часть программы.
Я говорю именно про модель, а не про всю программу. Хотел бы про программу писал бы программа. Зачем вносить путаницу?
Z>>Рич модель не позволяет, а с тонкой можно проделать все что угодно в коде бизнес процессов. G>И что?
Z>>В обеих моделях есть некое ядро, работая с которым нарушить логику невозможно. Интерфейс работы с этим ядром в жирной модели выглядит более богатым, а код самого ядра более компактным. Соответственно проще его верификация. G>Не надо ударяться в философию. G>В стройной модели есть данные и есть методы работы с ними. Никаких "ядер" "интерфейсов" и прочей мути. G>Если есть пример, показывающий обратное — можешь привести.
Это не философия, если ты не выделяешь подобного ядра — тебе надо быть уверенным во всей программе.
G>Слепая вера — самое страшное в программировании.
Здравствуйте, ilvi, Вы писали:
I>Здравствуйте, Ocenochka, Вы писали:
O>> однако, всем известно, что проще купить лишний сервер, чем поддерживать запутанную архитектуру.
I>Поубивал бы тех, кто пустил эту фразу в народ I>Мало того, что перекладывание своих проблем на кошелек заказчика, так еще святая вера в то, что просто добавление еще одного сервера улучшит производительность. А какие изменения в архитектуру ПО вы собираетесь вносить, чтобы ваше приложение хотя бы не стало медленей работать от добавления еще одного сервера?
Ну имхо вы усложняете. It depends. В смысле, если сервер был 1, и добавить еще один -- это да, может быть очень заморочисто. А если их было 2 или 3 или больше, то добавить еще один -- обычно совершенно не сложно, т.к. архитектура уже приспособлена к децентрализации.
Здравствуйте, Ocenochka, Вы писали:
O> Плюс один — наличие актуальных данных на клиентах. Вообще-то, я согласен, но хочется рассмротреть все варианты пока есть возможность.
наличие более актуальных данных. актуальные они только в БД.
... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
Re[7]: Архитектура приложения с несколькими клиентами и одни
Здравствуйте, Ziaw, Вы писали:
Z>Здравствуйте, gandjustas, Вы писали:
Z>>>Обе модели отражают данные, обе могут делать это нетривиальными маппингами, что сказать-то хотел? Нетривиальный маппинг в тощей модели, скорее вреден, так как способствует persistance ignorance, т.о. лишая тощую модель одного из главных достоинств. G>>И почему же вреден? Примеры будут?
Z>Это обсуждалось на данном форуме тыщу раз. Воспользуйся поиском, пересказывать лень.
Я форум уже несколько лет читаю каждый день и нечего подобного вспонить не могу.
Может я чего-то не понял? В каких достоинств лишается стройная модель?
Z>>>С тощей моделью логика в БД уживается лучше, это логично ложится в концепцию БД==модель. G>>Это ты сам придумал. Z>Что лучше уживается или что логично ложится?
То что это вообще имеет какой-то смысл в данном обсуждении.
G>>Я узнав про DDD попытался написать прогу в чисто dddшном. К концу разработки код оброс обилием неDDDшных конструкций, от самого DDD осталось мало. При этом на началном этапе я очень много времени потратил на поддержку именно DDD. Z>Примеры неDDDшных конструкций в студию.
В основном дополнительные классы для работы с произвольными выборками. Не помню уже все давно это было и на делфи.
Z>>>Различие между программой и моделью не видно? G>>Модель (елси мы говорим не об артефакте анализа) — часть программы. Z>Я говорю именно про модель, а не про всю программу. Хотел бы про программу писал бы программа. Зачем вносить путаницу?
Еще раз модель — часть программы. Рассматривать модель отдельно от программы смылса нету.
Не бывает модель ценной сама по себе.
Z>>>Рич модель не позволяет, а с тонкой можно проделать все что угодно в коде бизнес процессов. G>>И что?
Z>>>В обеих моделях есть некое ядро, работая с которым нарушить логику невозможно. Интерфейс работы с этим ядром в жирной модели выглядит более богатым, а код самого ядра более компактным. Соответственно проще его верификация. G>>Не надо ударяться в философию. G>>В стройной модели есть данные и есть методы работы с ними. Никаких "ядер" "интерфейсов" и прочей мути. G>>Если есть пример, показывающий обратное — можешь привести.
Z>Это не философия, если ты не выделяешь подобного ядра — тебе надо быть уверенным во всей программе.
А если бы выделял ядро, то не надо было бы быть уверенным?
Я вообще-то тесты пишу.
Re[8]: Архитектура приложения с несколькими клиентами и одни
Здравствуйте, gandjustas, Вы писали:
G>То что это вообще имеет какой-то смысл в данном обсуждении.
ок, проехали.
Z>>Примеры неDDDшных конструкций в студию. G>В основном дополнительные классы для работы с произвольными выборками. Не помню уже все давно это было и на делфи.
Почему ты решил, что эти кклассы "неDDDшные"? Рич модель не обязана состоять только из персистных классов. Она отличается от тонкой только тем, что допускает логику в персистных, но нигде не говорится об обязательном отсутствии BL в других классах.
G>Еще раз модель — часть программы. Рассматривать модель отдельно от программы смылса нету. G>Не бывает модель ценной сама по себе.
Z>>Это не философия, если ты не выделяешь подобного ядра — тебе надо быть уверенным во всей программе. G>А если бы выделял ядро, то не надо было бы быть уверенным?
Это уже пошла философия. Есть критические ошибки в БЛ, которые стоят очень дорого. Есть некое ядро, при корректности которого нарушить БЛ сложно/невозможно. Чем компактнее это ядро, тем легче его поддерживать. Я убежден, что рич модель позволяет сделать такое ядро более компактным и проще поддерживаемым. Правда требует большей квалификации при его дизайне.
Пример из практики, при переводе на клиент-сервер одной из систем сделали из рич модели тощую, руководствуясь примерно теми же мотивами, что и ты декларируешь. Ядро логики мне не удалось изолировать так же хорошо как и в жирной, хотя я проектировал ее на три года позже чем жирную (смею надеяться, что за три года в голове прибавилось ). Реюз кода уменьшился и, как я ни старался, сейчас требуется намного больше знаний о системе для написания новой логики. Сейчас я уже не так уверен, что решение проблем рич модели было бы дороже. И уж точно не сомневаюсь в праве рич моделей на жизнь.
G>Я вообще-то тесты пишу.
Дада, и в твоих программах больше нет ни одной ошибки. Рич модель несоместима с тестами чтоли?
... << RSDN@Home 1.2.0 alpha 4 rev. 1176>>
Re[4]: Архитектура приложения с несколькими клиентами и одни
Здравствуйте, MozgC, Вы писали:
O>>Не очень понимаю как отслеживать изменения. Допустим на клиенте грид с коллекцией объектов. При редактировании в отдельную коллекцию складывать отредактированные объекты? А как порядок редактирования учитывать? MC>Вы видимо невнимательно прочитали тему. Либо реализовывать флаг IsDirty в самом бизнес-объекте (базовом классе), либо использовать Wrapper, который будет отслеживать изменения обертываемого объекта и реализовывать флаг IsDirty. Если нужно учитывать порядок редактирования — это отдельная задача, но лично мне никогда не нужно было учитывать порядок редактирования.
Не, это я как раз понял, только там обсуждение было в контексте датасетов, что меня сразу не обрадовало. Общий смысл понятен.
MC>Вы уверены что вы заранее не усложняете задачу зачем-то?
Ну может слегка Не известно же что завтра заказчику в голову ударит, вот и пытаюсь импровизировать.
O>>>> — возникает необходимость хранить список изменений или передавать все потенциально измененные объекты; MC>>>Смотрите тему http://rsdn.ru/forum/design/3367411.flat.aspx
O>>Прочитал. Понял не много и легче не стало. MC>Может стоит еще раз внимательно прочитать? Я серьезно.
Прочитал. Понял не на много больше, чем после первого прочетния.
O>>Врапперы над сущностями и их коллекциями — это круто. Не совсем представляю как это будет в случае с несколькими клиентами. MC>Видимо у каждого клиента будет своя коллекция обернутых объектов.
Ага, теперь понятно.
O>>DataSet то же не хотелось бы, не то, чтобы я сильно религиозен, но мозги придется перекраивать сновательно. MC>В принципе датасеты вариант, но лично мне кажется что они провоцируют дублирование логики, а так же вынос логики в presentation. К тому же нетипизированные датасеты неудобны отсутствием типизации, а типизированные датасеты дают мало контроля, т.к. все генерируется и перегенерируется автоматически.
Вот вот, поэтому и не хочу с ними связываться.
O>>А последовательность изменений не учитывать? Если пятая операция из 10 не прошла, то, на мой взгляд, логично откатить все 10. Соответственно, пользователю прдется переделывать все 10. MC>Ну это зависит от задачи. Если мы принимаем 10 заказов от разных клиентов (через веб-сервис к примеру) и принялись только 5, после чего возникла ошибка — то откатывать все не нужно, просто запросить те которые не принялись и попытаться их сохранить. Если же действия должны быть "атомарными", то да, откатываем все 10. Но видимо у нас с вами тут какое-то недопонимание, потому как я не понимаю, почему пользователю придется переделывать все 10? К примеру пользователь открывает форму с разными полями для редактирования и гридом, что-то там изменяет и жмет сохранить. Если где-то косяк (к примеру ошибка валидации или ваша любимая коллизия), то пользователю просто сообщится о конкретной ошибке ("Product price can not exceed $100000"), на форме же останутся изменения сделанные пользователем. Пользователь исправляет что нужно и жмет Сохранить еще раз.
Хороший варант, только усложняет обработку ошибок, хотя может и не так сильно как мне кажется. Спасибо.
MC>Если же вы про облом операции именно по причине коллизии, то тут надо сначала знать, что должно происходить в случае коллизии? Может просто молча должны записаться изменения пользователя (на мой взгляд зачастую это вполне допустимо), или же надо сообщить пользователю о том что в БД уже етсь измененная версия объекта и спросить хочет ли он ее перезаписать? Или же надо перечитать (или просто отдельно показать) измененный объект из БД? Или надо все перечитать? Это вы должны сначала вместе с экспертами предметной области решить как должна вести себя система.
Вот это мне и не нравится, ибо сложности предметной области в данном случае могут вылиться в большой объем логики обработки таких ошибок. Подозреваю, что проще лочить объекты перед началом редактирования.
O>>>> б) либо на каждое действие пользователя включать курсор "песочные часы" и отправлять изменения на сервер — в принципе, O>>>> не вижу проблем, но почему-то не часто его встречаю (а может реже замечаю) — если есть проблемы, хотелось бы их узнать. MC>>>Это просто неправильно так делать. O>>Не правильно делать категоричные заявления без аргументов Ясно, что производительность и отзывчивость могут пострадать, если клиентов будет много, а сервер далеко, но есть подозрение, что дело не в этом. MC>И в этом тоже. Вы вообще искренне считаете что нормально отправлять изменения и сохранять их на сервере по каждому чиху пользователя? А если он решит отменить изменения?
Изменение решения — это уже достаточный аргумент. Опять спасибо.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Люблю ставить оценки.
Re[6]: Архитектура приложения с несколькими клиентами и одни
Здравствуйте, gandjustas, Вы писали:
G>>>Наверное при нажатии save, но в таком случае и передавать на сервер не надо. O>> Как не надо? А как об изменении смогут узнать другие клиенты? G>Сам же написал что без обратной связи. Тогда зачем до save куда-то что-то передавать?
Обратная связь — это когда сервер уведомляет клиентов об изменении. А когда с клиента на сервер передавать — сразу или при нажатии на сейв — это не обратная связь.
O>>>>>>Интересно какие в этом решении еще могут быть проблемы и как с ними бороться. Тестовый прототип уже пишу, но все равно хочу знать мнение практикующей общественности. G>>>>>В таком решении ты найдешь тысячи граблей, с которыми будешь долго бороться. O>>>> Пока не вижу у нас единого взгляда на это решение, учитывая заданные мне вопросы. G>>>А ты подробнее распиши задачу и покажи свои наработки. O>> Задача занимает сейчас около 100 стр. при этом я не могу понять что даст раскрытие ньюансов конкретной предметной области. Премер я уже приводил. Наработки еще не закончены, однако есть четкое представление архитектуры. G>Может дать очень много потому что единственное что сейчас видят люди на форуме — это твое трактование предметной области.
И для них этого вполне достаточно, судя по многим адекватным коментариям, которые я понимаю.
G>>>Создавать сферическую архитектуру в вакууме не получится. O>> Однако, глядя на ваши ответы, я считаю, что у вас это вполне получается Без обид. O>>Просто я не вижу у вас понимания решения N1. G>Это у тебя нету понимания решения N1, я такие решения в разных видах уже делал.
С тонкой domain model делал?
O>>То, что вы пробовали городить dataset'ы — это я уже выяснил G>Мимо. Как раз решения с dataset я предпочитаю не городить, я один раз начал такое делать и быстро отказался.
А как делал?
O>>и то что опыта с orm и domain model не имели то же выяснил G>Совсем мимо. С orm работаю постоянно и даже свой писал. G>Хреновый из тебя телепат.
Я и не претендовал Жду доказательств своей хреновости в виде ответов на вопросы
O>>>>>> Воообще, интересуют любые решения практикующих разработчиков, а так же мнения относительно адекватности двух приведенных мною решений. Адекватность прошу оценивать по времени написания, отладки и поддержки. G>>>>>Оба неадекваты на 99% O>>>> Предлагайте! G>>>Сделать кнопку Save, по которой сохранять изменения. G>>>Далее 3 варианта: G>>>1)Локальная реплика БД, которая хранит измененные данные (dataset или SQL CE) и периодическая синхронизация с сервером (передача changeset датасета или Sync Services для SQL CE) O>> В задаче сказано, что БД — одна. G>И что? SQL CE — несколько dll и больше ничего не надо
Я знаю, что такое SQL CE и работал с ней, однако, синхронизация должна быть чаще чем раз в минуту. Городить для этого репликацию из локальных БД... Синхронизацию руками проводить? Чем локальный кэш NHibernate хуже, чем локальная БД?
G>>>2)Написать кучу сервисов и DTO O>> Это зачем и к чему? G>Ко всему. Если клиент не толстый, то лучше увеличить гранулярность обращения к серверу. Для этого потребуется метод сервиса и вероятнее всего DTO.
Клиент толстый.
G>>>3)Воспользоваться EF\Linq2SQL+ADO.NET Data Services O>> Каким образом? G>Создть модель в EF дизайнере, создать сервис ADO.NET, сделать клиент.
Не пробовал EF, слышал негативные отзывы, как работает — не представляю. В чем преимущества?
O>> Есть четкая задача, которую я обозначил дважды, повторю еще раз: есть два клиента, работающих с общей БД. Как реализовать их работу при отсутствии коллизий? G>Наверное при наличии коллизий. Варианта как всегда два: G>1)пессимистичная блокировка — когда данные могут меняться только одним клиентом в один момент времени. G>2)оптимистичная блокировка, когда оба редактируют данные, если при попытке сорхнанить версии не сопадают — исправить конфликт и попытаться еще раз. G>Оптимистичная блокировка на самом деле блокировкой не является, несмотря на назание, и в некоторых случаях не работает.
Почему не работает? У же который раз пишут, что может не работать, однако я не представляю как это возможно в случае наличия версии в каждой сущности и транзакционной БД.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Люблю ставить оценки.
Re[12]: Архитектура приложения с несколькими клиентами и одн
Здравствуйте, Sinix, Вы писали:
O>> А как можно некорректно изменить данные, которые имеют версию? Два лока сделать одновременно ведь не удасться даже теоретически, на сколько я понимаю. S>А вот это очень распространённое заблуждение — верить что программа ценна сама по себе, и не потребуется интеграция с другими системами.
А если потребуется, от что? Нельзя будет учесть версию объекта, или транзакционность БД как-то отменится?
S>Данные у вас лежат в СУБД — любой запрос может помацать их несмотря ни на какие псевдоблокировки.
Раскажите, наконец, каким образом? Например, есть объект "клиент" у него есть свойство "счет". Объект имеет версию, лежит в БД. Дав клиента забирает его из БД, изменяют и пытаются положить обратно предварительно проверив версию объекта. Как возможна коллизая, эсли "помацать" — это коллизия ?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Люблю ставить оценки.
Re[2]: Архитектура приложения с несколькими клиентами и одни
Здравствуйте, meowth, Вы писали:
M>Прежде всего, вариант N2 следует отмести как нереализуемый -- уж очень много всяких косяков там вылезает: начиная от проблем с проксями NHibernate и заканчивая сбоями сети. Кроме того, работа по сети в таком случае выльется в безобразные тормоза на клиенте.
Это я понимал с самого начала, но товарищ с которым буду работать прделагал такой вариант, поэтому решил рассмотреть и его то же.
M>Итак, остается вариант №1, которым обычно и пользуются при написании 3хзвенок. M>Чтобы претворить его в жизнь, нужно: M>1) Определиться с генератором DTO: будет он или вы сами будете гонять отсоединенные объекты (DTO можно готовить и руками, но лучше взять что-либо типа otis lib);
Не понял, что подразумевается под генератором DTO. Пока решено гнять тонкие бизнес-объекты, а в тонких местах — DTO.
Сейчас начинаю понимать, что наличие единого сервера не нужно, поэтому клиенты будут просто получать из БД (от NHibernate) бизнес объекты и лочить/апдейтить их самостоятельно, а не через сервер. Соответственно, необходимость в DTO отпадает, как я понимаю.
M>2) Кнопка Save в вашем случае -- отличное решение; нужно только определиться с сеансами редактирования (т.е. где эти кнопки будут находиться и каковы будут участки, работа на которых идет от сохранения до сохранения;
Согласен, это не так сложно в моем случае.
M>3) Определиться с тем, как вы будете решать конфликты одновременного обновления: пессимистический вариант и оптимистический, соотственно. M>В случае пессимистического вы не допускаете конфликтов -- при помощи транзакций БД(хардкор, но иногда допустим или на уровне бизнес-транзакций (т.н. conversation), помечая и блокируя бизнес-объекты , находящиеся в редактировании; M>В случае оптимистического варианта вы решаете разруливать конфликты одновременного обновления по факту обнаружения таких конфликтов. Вариантов здесь а)затирать старые изменения (игнорируем конфликт) б) не давать затирать при помощи проверки версии (NHibernate вам в помощь) и просить пользователя внести вторично правку в устаревшие данные в) реализовать стратегию merge данных, если данные могут быть объединены без логического конфликта M>Ничего не мешает сочетать эти варианты, согласуясь с другими критериями.
Да, решено уже по мере надобности сочитать разные блокировки. Пугает только, что это может вылиться в большой объем логики обработки исключений конфликтов.
M>Да, и ответ на ваш вопрос -- NHibernate сам умеет поддерживать версии объекта, так что коллизий не будет; если вам интересно, я напишу следующим сообщением, почему описанная вами ситуация не случится.
Я и сам догадываюсь, но все равно напишите, т.к. я не знаю как это выразить словами. То, что NHibernate поддерживает <version> я знал, но использовать не приходилось и смутно представляю реализацию в sql. Видимо при апдейте идет проверка, что свойство version = currentVersion.
M>4) Определитесь со стратегией кеша и провайдером кеша (не все из них поддерживают блокировку объектов!). Со своей стороны могу порекомендовать SharedCache.net, ибо пробовал, понравилось; memcached не пробовал, но буду в след. проекте;
Кэша в NHibernate вроде всего два — один SysCache для asp.net, второй — некий Prevalence. В детали пока не вдавался. Мы об одном и
том же кэше говорим?
M>5) Определиться со стратегией выработки Id(PK) для бизнес-объектов -- некоторые, например, identity, плохо совместимы с NHibernate 2nd level cache.
Пока всегда хватало сурогатного Int64.
M>Если заинтересовало, пишите, продолжим обсуждение трудностей и подводных камней.