Re[20]: Некоторые мысли о LINQ
От: IB Австрия http://rsdn.ru
Дата: 10.01.09 10:01
Оценка:
Здравствуйте, Tissot, Вы писали:

T>То есть иди на фик.

Ну я так и думал, что сказать нечего.

T>Какой такой недостаток есть в LINQ2SQL-е, что он не позволяет построить domain model?

T>>и почему с его помощью нельзя построить domain model?
IB>Можно, но не нужно, <...>

Принципиально не читаешь, что тебе пишут? Еще раз — позволяет, но в этом нет необходимости.
... << RSDN@Home 1.2.0 alpha 4 rev. 1082>>
Мы уже победили, просто это еще не так заметно...
Re[33]: Некоторые мысли о LINQ
От: Tissot Россия  
Дата: 10.01.09 12:31
Оценка:
Здравствуйте, Sinclair, Вы писали:

T>>Откуда CustomerManager и как он может помешать изменить Customer-а напрямую?

S>Как откуда? Это и есть класс, в котором сосредоточены методы управления кастомерами.

Все равно вопросы остаются. Не совсем понятно где располагать методы, манипулирующие несколькими типами сущностей.
Например, если чуть изменить тот пример с резервированием:
пусть в случае отсутствия на складе нужного количества товара, товар резервируется частично и информация о зарезервированном кол-ве сохраняется в заказе. То есть, если мы хотели заказать 50 стульев, а на складе оказалось только 20, то 20 и зарезервируется, а после того, как на склад довезут товар, можно будет до-зарезервировать оставшиеся 30 стульев.
В такой формулировке операция резервирования меняет как остатки на складе, так и строки заказа.
В DDD для такого сценария был бы заведен ReservationService, в котором и был бы расположен весь код и по списанию остатков, и по обновлению заказа.
А куда вы его поместите?

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


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

S>А вот запретить из прикладного кода вызовы апдейт-стейтментов можно в том числе и при помощи FxCop.

S>Это если не хватает культуры программирования.
S>Нужно просто отделить случайные ошибки от преднамеренных действий.

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

S>>>А если подумать головой, то окажется, что зип-код нужен только в тот момент, когда выполняется отгрузка товара. Если кастомер хочет заказать и заплатить, то нет никакой причины требовать от него валидность ненужного сейчас зип-кода.

T>>Ну это скорее аргумент в пользу изменени логики валидации — она должна запускаться только при определенном статусе заказа.
S>Это приведет к тому, что в приложении вообще не будет повторно используемого кода. Потому что в логику валидации зашито слишком много подробностей про окружение. А всего-то надо было применить регекс в нужный момент.

Не совсем верно выразился. В описанном случае отсутствие zip-кода или его невалидность вообще не должно учитываться при валидации кастомера. Это действительно, скорее пред-условие для осуществления отгрузки.
Re[34]: Некоторые мысли о LINQ
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.01.09 04:29
Оценка:
Здравствуйте, Tissot, Вы писали:

T>В DDD для такого сценария был бы заведен ReservationService, в котором и был бы расположен весь код и по списанию остатков, и по обновлению заказа.

T>А куда вы его поместите?
В этом подходе точно так же будет ReservationService. Как раз в rich domain model непонятно, где располагать такой метод — в заказе, в складе, или еще где.

А так у нас есть некий сервис, которому для работы нужны заказы (с определенным поведением), и склад.

T>В том-то и вопрос, как избежать случайных ошибок.

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

T>Не совсем верно выразился. В описанном случае отсутствие zip-кода или его невалидность вообще не должно учитываться при валидации кастомера. Это действительно, скорее пред-условие для осуществления отгрузки.

Я просто веду к тому, что в реальной жизни инвариантов, которые можно безопасно захардкодить в класс ентити, практически не встречается. В развитых системах те же предусловия на операции вообще задаются путем конфигурирования workflow, без какой-либо перекомпиляции.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[22]: Некоторые мысли о LINQ
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.01.09 07:18
Оценка:
Здравствуйте, Tissot, Вы писали:
T>Это не кастомер, это способ хранения информации о кастомере.
Правильно.

T>Ближе к телу. Что за атрибуты?

Например "ID следующего кастомера, которого нужно обрабатывать, если обработка этого не удалась".
Это в случае представления приоритета кастомеров на основе односвязного списка. Или "Customer Priority". Или "Customer Access Control List".
Кастомер может оказаться разрезанным на несколько entity. А может оказаться наоборот. Контактный телефон может оказаться атрибутом кастомера; может оказаться атрибутом сущности "представитель кастомера", может оказаться отдельной сущностью, которая связана с первыми двумя отношением "многие-ко-многим".
При этом, что характерно, сама предметная область никак не меняется от этих страшных манипуляций. Какая из этих моделей domain model? Та, которая ближе к "предметной области"? Предметная область бесконечно сложна. К примеру,

S>>Этакие "артефакты модели". Задача "максимально приблизиться к предметной области" звучит хорошо, но работает плохо. Мне больше нравится задача "придумать максимально простую модель предметной области, которая покрывает максимальное количество пользовательских сценариев".


T>Такой моделью как раз и является domain model

Боюсь тебя разочаровать, но "максимальная близость к предметной области", которую ты постулировал как основной признак domain model, здесь может получиться только случайно.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[23]: Некоторые мысли о LINQ
От: Tissot Россия  
Дата: 11.01.09 07:48
Оценка:
Здравствуйте, Sinclair, Вы писали:

T>>Ближе к телу. Что за атрибуты?

S>Например "ID следующего кастомера, которого нужно обрабатывать, если обработка этого не удалась".
S>Это в случае представления приоритета кастомеров на основе односвязного списка.

Зачем это ID делать атрибутом Customer-а?

S>Или "Customer Priority".


Вполне себе атрибут предметной области.

S>Или "Customer Access Control List".


Внешняя по отношению к кастомеру сущность. По крайней мере у нас.

S>Кастомер может оказаться разрезанным на несколько entity. А может оказаться наоборот. Контактный телефон может оказаться атрибутом кастомера; может оказаться атрибутом сущности "представитель кастомера", может оказаться отдельной сущностью, которая связана с первыми двумя отношением "многие-ко-многим".

S>При этом, что характерно, сама предметная область никак не меняется от этих страшных манипуляций. Какая из этих моделей domain model?

Это вообще вопрос маппинга на хранилище. У нас не проекте как раз недавно такой рефакторинг делался. Объектная модель не поменялась. Почти

S>Та, которая ближе к "предметной области"? Предметная область бесконечно сложна. К примеру,


В программе не интересна "вся" сложность кастомера. Интересно лишь то, что ... хм, интересно. Собственно как раз это и отквочено ниже.

S>>>Этакие "артефакты модели". Задача "максимально приблизиться к предметной области" звучит хорошо, но работает плохо. Мне больше нравится задача "придумать максимально простую модель предметной области, которая покрывает максимальное количество пользовательских сценариев".


T>>Такой моделью как раз и является domain model

S>Боюсь тебя разочаровать, но "максимальная близость к предметной области", которую ты постулировал как основной признак domain model, здесь может получиться только случайно.

Ну это как вести метрику "близость".
Re[35]: Некоторые мысли о LINQ
От: Tissot Россия  
Дата: 11.01.09 08:01
Оценка:
Здравствуйте, Sinclair, Вы писали:

T>>В DDD для такого сценария был бы заведен ReservationService, в котором и был бы расположен весь код и по списанию остатков, и по обновлению заказа.

T>>А куда вы его поместите?
S>В этом подходе точно так же будет ReservationService.

То есть задача манипулирования заказами начинает расползаться на большее кол-во сервисов, не только на ЗаказМнеджер?

S>Как раз в rich domain model непонятно, где располагать такой метод — в заказе, в складе, или еще где.


rich model не отрицает наличие сервисов.

S>А так у нас есть некий сервис, которому для работы нужны заказы (с определенным поведением), и склад.


с поведением?

T>>В том-то и вопрос, как избежать случайных ошибок.

S>Очень трудно сделать случайную ишибку, если есть определенные договоренности.

ой, не факт. на договоренности надейся, а сам не плошай.

T>>Не совсем верно выразился. В описанном случае отсутствие zip-кода или его невалидность вообще не должно учитываться при валидации кастомера. Это действительно, скорее пред-условие для осуществления отгрузки.

S>Я просто веду к тому, что в реальной жизни инвариантов, которые можно безопасно захардкодить в класс ентити, практически не встречается.

Да есть инварианты, просто с zip-кодом вариант не не совсем удачный. С тем же заказчиком изначально заключается договор и в нем обговорены многие данные о заказчике. Так что они вполне могут проверяться в самой сущности.
Re[14]: Некоторые мысли о LINQ
От: Tissot Россия  
Дата: 11.01.09 08:03
Оценка:
Здравствуйте, Tissot, Вы писали:

T>>>

T>>>Во-вторых, добавляя новое поведение, надо его просто добавлять, а не менять старое

IB>>А это тут причем? При изменении требований новое поведение должно добавляться без изменения старого, это для тебя новость?

T>

T>Код должен быть поменян, а данные — нет.
T>(с) IB

T>

Поставил минус и в кусты. Ты (IB) уж расскажи, как могут сосуществовать "Код должен быть поменян" с "новое поведение должно добавляться без изменения старого"?
Интересно же.
Re[24]: Некоторые мысли о LINQ
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.01.09 08:11
Оценка:
Здравствуйте, Tissot, Вы писали:

T>Зачем это ID делать атрибутом Customer-а?

А чьим?

S>>Или "Customer Access Control List".

T>Внешняя по отношению к кастомеру сущность. По крайней мере у нас.
И какому объекту предметной области она соответствует?

T>Это вообще вопрос маппинга на хранилище. У нас не проекте как раз недавно такой рефакторинг делался. Объектная модель не поменялась. Почти

Это вопрос выбора сущностей для моделирования.

T>В программе не интересна "вся" сложность кастомера. Интересно лишь то, что ... хм, интересно. Собственно как раз это и отквочено ниже.

Вот и оказывается, что в модель попадает не всё, что было в "предметной области", и попадает то, чего там отродясь не было.

T>Ну это как вести метрику "близость".

Как ни вводи — всегда останется возможность привести контрпримеры.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[24]: Некоторые мысли о LINQ
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 11.01.09 08:12
Оценка:
Здравствуйте, Tissot, Вы писали:

T>Ну это как вести метрику "близость".




Ну вообще ваша "domain model по фаулеру" наиболее близка к предметной области по вашей метрике. Это же оченивдно.
Re[25]: Некоторые мысли о LINQ
От: Tissot Россия  
Дата: 11.01.09 08:43
Оценка:
Здравствуйте, Sinclair, Вы писали:

T>>Зачем это ID делать атрибутом Customer-а?

S>А чьим?

"ID следующего кастомера, которого нужно обрабатывать, если обработка этого не удалась"

Зачем это ID в кастомере? Просто передавай в метод обработки список кастомеров.

S>>>Или "Customer Access Control List".

T>>Внешняя по отношению к кастомеру сущность. По крайней мере у нас.
S>И какому объекту предметной области она соответствует?

Мне кажется ты слишком узко трактуешь понятие "предметная область". Это не обязательно что-то, что существует в предметном мире. Это вполне может быть и концепцией. Например, если говорят о ресурсах, доступных кастомеру, то понятие "доступ" к ресурсу существует в предметной области. А ACL — это не более чем набор этих "доступов".

T>>Это вообще вопрос маппинга на хранилище. У нас не проекте как раз недавно такой рефакторинг делался. Объектная модель не поменялась. Почти

S>Это вопрос выбора сущностей для моделирования.

Опять 25. Если для тебе данные — это сущность, то да, если для тебя (меня) сущность — это сущность domain model, то нет.

T>>В программе не интересна "вся" сложность кастомера. Интересно лишь то, что ... хм, интересно. Собственно как раз это и отквочено ниже.

S>Вот и оказывается, что в модель попадает не всё, что было в "предметной области", и попадает то, чего там отродясь не было.

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

T>>Ну это как вести метрику "близость".

S>Как ни вводи — всегда останется возможность привести контрпримеры.

Возможно. Я вроде и не говорил, что доменная модель — это конец истории. Все когда-нить уйдет. Но вот придет ли на смену ей тот подход о котором вы говорите —
Время покажет.
Re[15]: Некоторые мысли о LINQ
От: IB Австрия http://rsdn.ru
Дата: 11.01.09 08:44
Оценка:
Здравствуйте, Tissot, Вы писали:

T>Поставил минус и в кусты.

Ты же сам отказался со мной дискутировать, так чего бисер метать?

T>Ты (IB) уж расскажи, как могут сосуществовать "Код должен быть поменян" с "новое поведение должно добавляться без изменения старого"?

Про OCP принцип слышал? Поинт в том, что при добавлении новго функционала, та часть исходников, которая реализует старый и все еще актуальный функционал даже трогаться не должна, а не только не меняться. Меняется и трогается только то, что нужно изменить. Необходимость менять данные возникает гораздо реже, чем логику, которая навернута поверх этих данных. Таким образом, выделяя данные в отдельную сущность мы защищаем их от лишних изменений, трогая только тот код, который должен поменяться.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[25]: Некоторые мысли о LINQ
От: Tissot Россия  
Дата: 11.01.09 08:44
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>


G>Ну вообще ваша "domain model по фаулеру" наиболее близка к предметной области по вашей метрике. Это же оченивдно.


См. ответ Синклеру.
Re[36]: Некоторые мысли о LINQ
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.01.09 08:46
Оценка:
Здравствуйте, Tissot, Вы писали:

T>То есть задача манипулирования заказами начинает расползаться на большее кол-во сервисов, не только на ЗаказМнеджер?

Всё зависит от конкретной задачи. Не забываем про Single Responsibbility Principle.
То есть наш xxxService должен делать всё, что относится к соответствующей ответственности. Речь не идет о тупом механическом выносе всех методов из класса Xxx в класс XxxManager.

T>rich model не отрицает наличие сервисов.

Ну, ты только что боролся за то, чтобы методы включать в entity. Опять напомню, что ReservationService не соответствует вообще ничему в предметной области; таким образом, мы уходим от твоей "максимально близкой к предметной области модели".

T>с поведением?

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

T>ой, не факт. на договоренности надейся, а сам не плошай.

Опять же, для плохих танцоров есть FxCop.

T>Да есть инварианты, просто с zip-кодом вариант не не совсем удачный. С тем же заказчиком изначально заключается договор и в нем обговорены многие данные о заказчике. Так что они вполне могут проверяться в самой сущности.

Какие например? Договор заключается с каждым отдельным заказчиком. Надеюсь, ты не предполагаешь каждый раз писать новый класс сущности для него?
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[15]: Некоторые мысли о LINQ
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.01.09 08:46
Оценка:
Здравствуйте, Tissot, Вы писали:
T>Поставил минус и в кусты. Ты (IB) уж расскажи, как могут сосуществовать "Код должен быть поменян" с "новое поведение должно добавляться без изменения старого"?
T>Интересно же.
Это просто два разных сценария. В одном на существующих данных применяются новые методы, а старые вообще выбрасываются из рассмотрения. Это — замена функциональности.
Она типична, например, когда мы берем накопленные за годы данные и передаём их третьим лицам для data mining.
Дата майнингу совершенно неинтересна валидация, workflow, и прочие приколы, которыми мы пользовались в исходном OLTP приложении. Более того, для него крайне вредно иметь всякие такие штуки типа "адрес кастомера вычисляется полиморфно в зависимости от его типа и параметров", потому что вместе с данными придется тащить вот это "полиморфное поведение". Которое, в частности, может вообще не заработать на той платформе, где датамайнинг собрались выполнять.

В другом случае речь идет о расширении функциональности существующей системы.
И в нём важна возможность произвести это расширение с минимальными потерями. Зашивание логики в data objects чревато неконтролируемым расползанием изменений.
Вот мы по соседству обсуждали валидацию зипкодов. Буквально за два дня у нас код валидации изменился не то четыре, не то пять раз — в зависимости от вторичных подробностей. Это признак того, что с самого начала было сделано что-то неправильно. Если поддержка еще одной страны требует внесения изменений в классы кастомера, заказа, и еще хрен знает чего, то как-то становится жалко потраченных на разработку усилий.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[16]: Некоторые мысли о LINQ
От: Tissot Россия  
Дата: 11.01.09 08:58
Оценка:
Здравствуйте, IB, Вы писали:

T>>Поставил минус и в кусты.

IB>Ты же сам отказался со мной дискутировать, так чего бисер метать?

Опять хамишь. Ты что, без этого совсем не можешь?

T>>Ты (IB) уж расскажи, как могут сосуществовать "Код должен быть поменян" с "новое поведение должно добавляться без изменения старого"?

IB>Про OCP принцип слышал?

Слышал конечно (зевок). Я же тебе же отвечал, что я не со школьной скамьи сюда пришел.

IB>Поинт в том, что при добавлении новго функционала, та часть исходников, которая реализует старый и все еще актуальный функционал даже трогаться не должна, а не только не меняться. Меняется и трогается только то, что нужно изменить.


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

добавляя новое поведение, надо его просто добавлять, а не менять старое

, если какая-то часть исходников все-таки трогается.

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


Тут имхо, идет смешение понятий.
То, о чем ты говоришь — это защита схемы данных (контракт), а не самих данных. Данные как раз мы не защищаем, а наоборот выставляем напоказ.
Re[26]: Некоторые мысли о LINQ
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.01.09 09:03
Оценка: 2 (1) +1
Здравствуйте, Tissot, Вы писали:
T>Зачем это ID в кастомере? Просто передавай в метод обработки список кастомеров.
Откуда возьмется "список"?

T>Мне кажется ты слишком узко трактуешь понятие "предметная область". Это не обязательно что-то, что существует в предметном мире. Это вполне может быть и концепцией. Например, если говорят о ресурсах, доступных кастомеру, то понятие "доступ" к ресурсу существует в предметной области.

Об этом я и говорю. Вот эта "предметная область" — нифига не "предметная область". Это "модель предметной области", которая сделана по некоторым соображениям.
Имхо, Фаулер говорил именно о предметной области, а не об артефактах, вызванных моделированием.

T>Опять 25. Если для тебе данные — это сущность, то да, если для тебя (меня) сущность — это сущность domain model, то нет.

А ты попробуй всё-таки понять, что такое "domain model". Что именно там domain?

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

Как артефакт анализа. Простейшая штука — ID. В предметной области никаких суррогатных ключей нету. В данных почему-то появляются.
В предметной области нет никаких понятий типа "доступа", они появляются только после моделирования. Этакие "сущности второго порядка".

В развитом приложении, к примеру, правила валидации сами становятся "сущностями", хотя никакому объекту в предметной области они не соответствуют.

В итоге, применение ООП для моделирования "реального мира" в большинстве случаев совершенно бесполезно.

Вообще, напомню, что ООП появилось как попытка разработать удачную абстракцию для оконно-ориентированного GUI. Именно поэтому в ранних книгах по ООП так много примеров на тему pWindow->draw() или pFigure->draw().
Прошли годы, и оказалось, что даже для этих задач ООП в таком виде малопригодно.
Что окна удобнее собирать из готовых примитивов как агрегаты, а не наследовать друг от друга.
Что и геометрические фигуры не надо наследовать друг от друга, а достаточно иметь ровно один класс VectorPath, который рисуется ровно одним образом, а бытность его квадратом или треугольником — всего лишь предикат, а не имманентное свойство.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[37]: Некоторые мысли о LINQ
От: Tissot Россия  
Дата: 11.01.09 09:12
Оценка:
Здравствуйте, Sinclair, Вы писали:

T>>То есть задача манипулирования заказами начинает расползаться на большее кол-во сервисов, не только на ЗаказМнеджер?

S>Всё зависит от конкретной задачи. Не забываем про Single Responsibbility Principle.

Ответственности тоже можно порезать по-разному. Можно — по модифицирующим сущностям (CustomerManager, OrderManager), можно и по бизнес — сценариям (ReservationService).

S>То есть наш xxxService должен делать всё, что относится к соответствующей ответственности. Речь не идет о тупом механическом выносе всех методов из класса Xxx в класс XxxManager.


Не, я пытаюсь понять как ты предлагаешь это сделать.

T>>rich model не отрицает наличие сервисов.

S>Ну, ты только что боролся за то, чтобы методы включать в entity.

Нет, я боролся за то, чтобы те сделать контракт сущности таковым, чтобы нельзя было нарушить инварианты. Если метод работы с сущностью не нарушает инвариантов, то его можно поместить и вовне класса, например в виде extension-метода, если мы используем C#. Если область действия метода шире чем данный экземпляр класса, то ему не место в классе, нужно завести отельный сервис, в котором и реализовывать необходимый функционал.

S>Опять напомню, что ReservationService не соответствует вообще ничему в предметной области; таким образом, мы уходим от твоей "максимально близкой к предметной области модели".


Дык, ReservationService и не является частью domain model. Это бизнес-операция.

T>>с поведением?

S>Ага. В простом случае достаточно прямой манипуляции данными; в более сложном ReservationService будет делегировать построение запросов для модификации позиций заказа и остатков на складах соответствующим сервисам.

T>>ой, не факт. на договоренности надейся, а сам не плошай.

S>Опять же, для плохих танцоров есть FxCop.

Ну так как его использовать, если функциональность изменения остатков на складе уже переползла из соответствующего менеджера в ReservationService?

T>>Да есть инварианты, просто с zip-кодом вариант не не совсем удачный. С тем же заказчиком изначально заключается договор и в нем обговорены многие данные о заказчике. Так что они вполне могут проверяться в самой сущности.

S> Какие например? Договор заключается с каждым отдельным заказчиком. Надеюсь, ты не предполагаешь каждый раз писать новый класс сущности для него?

Из того, что "Договор заключается с каждым отдельным заказчиком" не следует, что договоры с заказчиками не имеют ничего общего. Первое что приходит в голову — это название заказчика и SLA. Кроме того, каждый заказчик регистрируется в бухгалтерской системе, в которой он получает свой номер. Этот номер — второй претендент на проверку.
Re[16]: Некоторые мысли о LINQ
От: Tissot Россия  
Дата: 11.01.09 09:22
Оценка:
Здравствуйте, Sinclair, Вы писали:

T>>Поставил минус и в кусты. Ты (IB) уж расскажи, как могут сосуществовать "Код должен быть поменян" с "новое поведение должно добавляться без изменения старого"?

T>>Интересно же.
S>Это просто два разных сценария. В одном на существующих данных применяются новые методы, а старые вообще выбрасываются из рассмотрения. Это — замена функциональности.

S>В другом случае речь идет о расширении функциональности существующей системы.


Ладно, будем считать, что IB именно это и имел в виду, хотя из его слов это было совсем не ясно.

S>И в нём важна возможность произвести это расширение с минимальными потерями. Зашивание логики в data objects чревато неконтролируемым расползанием изменений.


Нет dataobjects в domain model, потому и такого явления как "зашивание логики в data objects", а следовательно нет и "расползанием изменений". domain model рулит!

S>Вот мы по соседству обсуждали валидацию зипкодов. Буквально за два дня у нас код валидации изменился не то четыре, не то пять раз — в зависимости от вторичных подробностей. Это признак того, что с самого начала было сделано что-то неправильно.


Правильно, не был проведен анализ.

S>Если поддержка еще одной страны требует внесения изменений в классы кастомера, заказа, и еще хрен знает чего, то как-то становится жалко потраченных на разработку усилий.


И какой вывод? Отказаться от валидации совсем? Дык это не решение, т.к. если на этапе анализа было решено, что валидация нужна, то и моем и в твоем случае ее делать придется.
Re[38]: Некоторые мысли о LINQ
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.01.09 09:38
Оценка:
Здравствуйте, Tissot, Вы писали:
T>Ответственности тоже можно порезать по-разному. Можно — по модифицирующим сущностям (CustomerManager, OrderManager), можно и по бизнес — сценариям (ReservationService).
Первый способ — неправильный; второй — правильный.

T>Нет, я боролся за то, чтобы те сделать контракт сущности таковым, чтобы нельзя было нарушить инварианты. Если метод работы с сущностью не нарушает инвариантов, то его можно поместить и вовне класса, например в виде extension-метода, если мы используем C#. Если область действия метода шире чем данный экземпляр класса, то ему не место в классе, нужно завести отельный сервис, в котором и реализовывать необходимый функционал.

Всё правильно. Повторюсь: при анализе предметной области тех инвариантов, о которых ты говоришь, возникает пренебрежимо мало.
Даже самые очевидные штуки, типа "остатки на складе не могут быть меньше нуля" в реальной жизни оказываются неверными (например, из-за того, что оприходование товара выполняется с опозданием).

T>Дык, ReservationService и не является частью domain model. Это бизнес-операция.

Ну вот очень странно получается — важное поведение не попадает в модель. Это получается какая-то плохая модель, некачественная. Непонятно, почему одно поведение входит в модель, а другое — нет.
В анемичной модели всё просто: "сущности" моделируют только статическую часть предметной области, у них нет никакого поведения. А всё поведение сосредоточено во всяких ...Manager, ...Service, ...Strategy, ...Policy.

T>Ну так как его использовать, если функциональность изменения остатков на складе уже переползла из соответствующего менеджера в ReservationService?

Очень просто — в данном сценарии ReservationService и стал "соответствующим менеджером"

T>Из того, что "Договор заключается с каждым отдельным заказчиком" не следует, что договоры с заказчиками не имеют ничего общего. Первое что приходит в голову — это название заказчика и SLA. Кроме того, каждый заказчик регистрируется в бухгалтерской системе, в которой он получает свой номер. Этот номер — второй претендент на проверку.

На проверку чего?
Намекну: бухгалтерская система может быть завтра заменена, без изменения бизнеса.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[17]: Некоторые мысли о LINQ
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.01.09 09:53
Оценка:
Здравствуйте, Tissot, Вы писали:

T>Нет dataobjects в domain model, потому и такого явления как "зашивание логики в data objects", а следовательно нет и "расползанием изменений". domain model рулит!

Ну щас прямо. То, что было бы в анемичной модели банальной структурой "кастомер", то бишь дата обжектом, в твоей "domain model" обрастает какими-то методами, валидацией там, и так далее. В итоге изменения таки расползаются.

T>Правильно, не был проведен анализ.

Почему это? Представь себе реальную жизнь — бизнес эволюционирует, требования, которых не было в Release 1, появляются в Release 2.
Как бы ты ни пыхтел в Release 1, всех требований ты предсказать не можешь

T>И какой вывод? Отказаться от валидации совсем? Дык это не решение, т.к. если на этапе анализа было решено, что валидация нужна, то и моем и в твоем случае ее делать придется.

Только в моём случае не придется менять класс Customer при изменении требований к валидации.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.