Здравствуйте, gandjustas, Вы писали:
S>>Не обижайтесь, но у вас какое-то идеализированное представление о проектировании систем — берём требования, реализуем и все щасливы. Нифига! G>Это действительно так. Достаточно накаждом этапе (сбор требований-анализ-проектирование-реализация) подключать мозг.
Завидую — у нас реально разные ситуации. Мы в принципе говорим об одном и том же, просто вы не рассматриваете предметную область как нечто самостоятельное.
Я вам привёл самый обычный пример про невозможность проверок в 1 месте.
До примера вы писали
Но если еще на этапе анализа включить мозг, то окажется что многие business-rules являются предусловиями к некоторым операциям
после:
Все что написано сильно зависит от предметной области и желаний заказчика.
Вы же сами пишете что предметная область всё-таки влияет на нюансы архитектуры приложения. Если я вырвал ваши слова из контекста — мои извинения, не так вас понял.
S>>Во-первых требования никогда не содержат полной информации о предметной области. Это отдельная тема, подробнее стоит почитать у апологетов DDD. G>И что? Разве кто-то мешает изучать предметную область? G>Лушче всего это делать на этапе анализа.
Ещё раз прошу — почитайте Эванса. Он классно расписал чем плох формальный подход к предметной области (и про анализ там тоже написано.) Ещё такое ощущение, что у вас разработка заканчивается с впариванием результатов заказчику — там такой подход конеш рулит.
S>>В-третьих если вам потребуется взаимодействие с внешними системами, от вас потребуется громадная куча фич, которые очевидны из предметной области, но не указаны в требованиях. G>Лушче всего это делать на этапе анализа.
... G>И что? Типа сначала надо модель предментной области забабахать, а потом думать как с ней программу написать. G>Это дурацкий подход мягко говоря. В первую очередь на что надо ориентироваться — требования, предметная область вносит дополнительные ограничения не более того.
А вот здесь вы вообще неправы. Основное проектирование систенмы делается (если делается вообще) на первых итерациях.
А все проблемы о которых я говорю появляются позже, когда система уже сдана и эксплуатируется. И вот тогда вы огребаете проблем по-полной, потому что любой минорный фикс убивет к [censored] весь дизайн. Потому то вы поверили в достаточность требований, которые заведомо не содержат полной информации. Не люблю я подход "сделал как просили". Хреново смотрится когда ты получил деньги, а потом выставляешь заказчика идиотом.
Скажите, как вообще можно строить дизайн системы на основе функциональных требований? Они же описывают только внешний интерфейс системы. Всё что вы можете сделать — провести кластеризацию графа зависимостей и выделить компоненты по степени связности. Этот дизайн нифига не будет стабильным — любое новое требование перекроит все зависимости и дизайн, заточенный под конкретный набор юз-кейзов будет только мешать развивать систему.
Блин, я не знаю, как объяснять очевидные вещи... понимаете, модель предметной области — это не структура данных, не куча бумажек, и уж тем более не отчёт аналитика. Это грубо говоря общая модель, которая используется всеми и позволяет общаться на одном языке с неспециалистами, легко проверять корректность требований и предвидеть что потребуется дальше. Ну и в подарок получаете дизайн устойчивый к самым неожиданным требованиям.
Естественно, сразу строить _полную_ модель предметной области будет только полный идиот — т.к. штука в принципе бесконечная. Но использовать модель надо с самого начала проекта и не отступать от этого использования (опять было написано у Эванса). Поэтому ваши утверждения что "модель лучше использовать на этапе анализа" смотрятся весьма странно. G>>>Для поиска багов лучше тесты. S>>[ОФФТОП] S>>Про тесты: одно другого не отменяет. Лично мне куда проще саппортить такой код: S>>[/ОФФТОП] G>Контракты — хорошо, только причем тут предметная область?
А почитайте всю цепочку — здесь предметная область не обсуждалась никак.
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
S>Я вам привёл самый обычный пример про невозможность проверок в 1 месте. S>До примера вы писали S>
S>Но если еще на этапе анализа включить мозг, то окажется что многие business-rules являются предусловиями к некоторым операциям
S>после: S>
S>Все что написано сильно зависит от предметной области и желаний заказчика.
S>Вы же сами пишете что предметная область всё-таки влияет на нюансы архитектуры приложения. Если я вырвал ваши слова из контекста — мои извинения, не так вас понял.
Естественно влияет — вносит дополнительные условия и ограничения в требования.
S> S>>>Во-первых требования никогда не содержат полной информации о предметной области. Это отдельная тема, подробнее стоит почитать у апологетов DDD. G>>И что? Разве кто-то мешает изучать предметную область? G>>Лушче всего это делать на этапе анализа.
S>Ещё раз прошу — почитайте Эванса. Он классно расписал чем плох формальный подход к предметной области (и про анализ там тоже написано.)
Я его читал. Я предлагаю не рассматривать"предметную область" как вещь в себе.
Ведь в конченом итоге надо сделать приложение, которое полезно людям, а не модель некоторой предметной области.
S>Ещё такое ощущение, что у вас разработка заканчивается с впариванием результатов заказчику — там такой подход конеш рулит.
Не совсем "впариваением", но смысл именно такой — чтобы заказчик был доволен.
S>А все проблемы о которых я говорю появляются позже, когда система уже сдана и эксплуатируется. И вот тогда вы огребаете проблем по-полной, потому что любой минорный фикс убивет к [censored] весь дизайн. Потому то вы поверили в достаточность требований, которые заведомо не содержат полной информации. Не люблю я подход "сделал как просили". Хреново смотрится когда ты получил деньги, а потом выставляешь заказчика идиотом.
Это зависит от закачика и от менеджера.
Есть люди которые понимают, то рекая программа пишется раз и навсегда, что любая неучнеттая мелочь может оказаться критической.
Если заказчик и менеджер это понимаю, то получаются хорошие программы. (хотя если менеджер не понимает, то его уволить надо)
А бывают заказчики, которые хотят побыстрее, подешевле и побольше. С такимми действительно лучше работать по принципу "сделали как просили".
S>Скажите, как вообще можно строить дизайн системы на основе функциональных требований?
Рецепты давно известны: слабая связность и следовать принципам KISS и YAGNI.
S>Они же описывают только внешний интерфейс системы. Всё что вы можете сделать — провести кластеризацию графа зависимостей и выделить компоненты по степени связности. Этот дизайн нифига не будет стабильным — любое новое требование перекроит все зависимости и дизайн, заточенный под конкретный набор юз-кейзов будет только мешать развивать систему.
Далеко не так. Ведь у нас есть не только пожелания заказчика, а есть еще и требования от предметной области.
Стартовый набор требований обычно достаточно большой, чтобы большая часть системы оставалась стабильной при всех изменениях.
S>Блин, я не знаю, как объяснять очевидные вещи... понимаете, модель предметной области — это не структура данных, не куча бумажек, и уж тем более не отчёт аналитика. Это грубо говоря общая модель, которая используется всеми и позволяет общаться на одном языке с неспециалистами, легко проверять корректность требований и предвидеть что потребуется дальше.
Угу Ubiquitous Language, проходили уже. А толку от него? Ну поговорили вы со специалистами на их языке, сделали требования корректныим.
Как это на дизайн приложения повлияет.
S>Ну и в подарок получаете дизайн устойчивый к самым неожиданным требованиям.
Если бы все было так хорошо, как на словах, то все бы давно использовали DDD.
Вот только DDD начинает отсасывать даже тогда, когда просто требуется добавить нетривиальную экранную форму для каких-либо целей.
S>Естественно, сразу строить _полную_ модель предметной области будет только полный идиот — т.к. штука в принципе бесконечная. Но использовать модель надо с самого начала проекта и не отступать от этого использования (опять было написано у Эванса). Поэтому ваши утверждения что "модель лучше использовать на этапе анализа" смотрятся весьма странно.
Вот становится весело, когда новые требования не укладываются в модель.
Например была какая-то банальная торговая система, а тут потребовалось внести возможность резервирования и предзаказа.
ЗЫ. Чем больше кода у вас написано и чем большей степенью свзяности он обладает, тем тяжелее вносить изменения.
Заранее всех изменений не предугадаешь, лучше писать меньше кода и оставлять больше точек расширения.
Здравствуйте, IB, Вы писали:
IB>Здравствуйте, Mike Chaliy, Вы писали:
MC>>У нас нет. Сериализация это такое же публичное АПИ. Для него есть контракты. IB>То есть, все таки сериализуется. Или все-таки нет? Ты не виляй ты прямо скажи.
Нет не сереализируеться.
MC>>Смешно, ты подсматрел то чего нет. Тебе не кажеться что ситуация слегка глуповатая? IB>Меня эта ситуация пока что забавляет. С одной стороны у тебя все зашибись и проблем ты в упор не видишь, а с другой ничего конкретного сказать не можешь, на прямые вопросы не отвечаешь. IB>Вывод, в принципе очевиден, но словоблудие забавное.. =)
Конкретное что? Я на любой конкретный вопрос по теме могу ответить. Я практикующий програмист.
MC>> Плаин ПОКО. Ни маркировочных атрибтов, ничего. Тока чистые методы и состояние — рай. IB>Так как ты свои ПОКО сериализуешь?
Я их НЕ сериализирую.
MC>>Мы на него таких респонсибилитей вообще не вешаем. IB>А какие вешаете?
Реализацию языка доменной модели.
Здравствуйте, gandjustas, Вы писали:
ЛИ>>1) Главная задача архитектора меняется в зависимости от типа проекта и даже его фазы. Могу по собственному опыту сказать, что зачастую она заключается в минимизации затрат на сопровождение и развитие. Хорошо приготовленная RDM в этом смысле превосходит ADM, и Вы перечислили причины почему в той части, где говорите о преимуществах RDM; G>Ну это просто неверно. Как ни крути, а rich нарушает SRP, что негативно сказывается на стоиомости сопровождения.
Если не секрет, вам во сколько становилось в цифрах? Имхо без конкретного примера это только разговоры.
ЛИ>>2) Переносимость бизнес-объектов между физическими звеньями (то есть за границы адресного пространства) -- довольно редкое требование, нет необходимости ориентироваться на него в общем случае. G>Я бы архитектора выгнал сразу за такие слова. G>Основа снижения издержек на развитие ПО — обеспечить повторное использование дизайнерксих решений. Говоря по русски — надо чтобы код не менялся даже если понадобится превратить двузвенное десктоп решение в веб.
Имхо вы долбанетесь переделывать его в веб с сохранением архитектуры. Вы как-то раньше сами жаловались на это. Кроме того, бизнес-объекты даже в случае миграции в сторону web-клиента не передаются в UI -- там используются DTO, поэтому ничто не мешает бизнес-объектам быть rich; наоборот, часто это даже удобно.
ЛИ>>Использование бизнес-объектов RDM в разных слоях в пределах одного физического звена при адекватных инструментах никакой проблемы не составляет; G>Ну жирные объекты с LL так просто не протащишь. Сложная логика также станет недоступна на клиенте, а методы из объектов никуда не денутся.
Речь об одном _физическом_ звене.
G>Еще раз? Какие премущества rich перед anemic? Бредятину типа "в ней больше ООП" не рассматриваем. G>Покажите пример кода, где по rich гораздо удобнее anemic.
Легко: ActiveRecord вам в руки. Для небольших проектов ну просто супер. Поюзайте ActiveWriter для простенького сайта или магазина, поймете, о чем я.
Только не надо заводить разговор о том, что Active Record -- это антипаттерн, потому что так кому-то приснилось.
Здравствуйте, Mike Chaliy, Вы писали:
MC>Нет не сереализируеться.
Ну, вы ребята тогда в какой-то альтернативной реальности живете, где объекты посредством страшного колдунства сами оказываются в базе, во внешнем файле, на другом сервере. Тут да, тут жирная модель возможно работает.. )
MC> Я на любой конкретный вопрос по теме могу ответить. Я практикующий програмист.
Пока не видно..
MC>Я их НЕ сериализирую.
Как они у тебя в базе оказываются?
MC>Реализацию языка доменной модели.
"С точки зрения банальной эрудиции, не каждый индивидуум способено лояльно игнорировать тенденции..." далее по тексту.
Спорим я больше умных слов знаю? Реализация — это не ответственность.
Здравствуйте, gandjustas, Вы писали:
ЛИ>>3) Если имеют место большие объёмы данных, то лучше вообще не связываться с Domain Model. К счастью, большинство транзакционных сценариев не предполагает большого количества объектов, а значит можно в полной мере использовать преимущества RDM; G>Еще раз? Какие премущества rich перед anemic? Бредятину типа "в ней больше ООП" не рассматриваем. G>Покажите пример кода, где по rich гораздо удобнее anemic.
Вот можем начать с этого.
Rich
public void CreateOrder(number){
var order = _orderFactory.Create(number);
order.AddItem(product1, weight);
order.AddItem(product2, weight);
_orderRepository.Add(order);
}
Anemic
public void CreateOrder(number){
validateOrderNumber(number);
var total = calcualteTotal(weight1, weight2);
validateIfTotalAcceptable(total);
var order = new Order(){Number = number, Total = total};
var item1 = new Item(){OrderId = order.Id, ProductId = product1.Id, Weight = weight1};
var item2 = new Item(){OrderId = order.Id, ProductId = product2.Id, Weight = weight2};
_orderDAL.InsertOrder(order);
_orderDAL.InsertOrderItem(item1);
_orderDAL.InsertOrderItem(item2);
}
Здравствуйте, meowth, Вы писали:
M>Здравствуйте, gandjustas, Вы писали:
ЛИ>>>1) Главная задача архитектора меняется в зависимости от типа проекта и даже его фазы. Могу по собственному опыту сказать, что зачастую она заключается в минимизации затрат на сопровождение и развитие. Хорошо приготовленная RDM в этом смысле превосходит ADM, и Вы перечислили причины почему в той части, где говорите о преимуществах RDM; G>>Ну это просто неверно. Как ни крути, а rich нарушает SRP, что негативно сказывается на стоиомости сопровождения. M>Если не секрет, вам во сколько становилось в цифрах? Имхо без конкретного примера это только разговоры.
В цифрах не могу, нету примера с жирной моделью и аналогичной ей стройной, чтобы сравнить.
Первое на что можно обратить внимание — необходимость согласовывать изменения в DTO и доменных объектах.
Второе — достачно сложное создание произвольных выборок.
ЛИ>>>2) Переносимость бизнес-объектов между физическими звеньями (то есть за границы адресного пространства) -- довольно редкое требование, нет необходимости ориентироваться на него в общем случае. G>>Я бы архитектора выгнал сразу за такие слова. G>>Основа снижения издержек на развитие ПО — обеспечить повторное использование дизайнерксих решений. Говоря по русски — надо чтобы код не менялся даже если понадобится превратить двузвенное десктоп решение в веб. M>Имхо вы долбанетесь переделывать его в веб с сохранением архитектуры.
Дык в том задача архитектора, чтобы не долбанулись программисты.
M>Вы как-то раньше сами жаловались на это.
Нет. Я говорил что тупо написанное десктом приложение в веб переделать практически невозможно.
Если такой вариант возможен, то прилождение надо писать умно.
Как раз сейчас наблюдаю массовый переход на веб, тех кто еще год назад даже не думал о таком.
M>Кроме того, бизнес-объекты даже в случае миграции в сторону web-клиента не передаются в UI -- там используются DTO, поэтому ничто не мешает бизнес-объектам быть rich; наоборот, часто это даже удобно.
Ну это у кого как.
У меня примерно на 60% вьюх передаются Presentation Entity, а в остальных вполне хватает тех самых объектов, вытащенных из базы.
Причем часто Presentation Entity состоит из нескольких объектов, вытащенных из базы.
ЛИ>>>Использование бизнес-объектов RDM в разных слоях в пределах одного физического звена при адекватных инструментах никакой проблемы не составляет; G>>Ну жирные объекты с LL так просто не протащишь. Сложная логика также станет недоступна на клиенте, а методы из объектов никуда не денутся. M>Речь об одном _физическом_ звене.
Да, что-то промазал.
G>>Еще раз? Какие премущества rich перед anemic? Бредятину типа "в ней больше ООП" не рассматриваем. G>>Покажите пример кода, где по rich гораздо удобнее anemic.
M>Легко: ActiveRecord вам в руки. Для небольших проектов ну просто супер. Поюзайте ActiveWriter для простенького сайта или магазина, поймете, о чем я.
Я как-то юзал ActiveRecord как раз для сайта, не заметил чтобы кода стало значительно меньше.
Кроме того все те же прооблемы с произвольными выборками.
Здравствуйте, IB, Вы писали:
IB>Здравствуйте, Mike Chaliy, Вы писали:
MC>>Нет не сереализируеться. IB>Ну, вы ребята тогда в какой-то альтернативной реальности живете, где объекты посредством страшного колдунства сами оказываются в базе, во внешнем файле, на другом сервере. Тут да, тут жирная модель возможно работает.. )
Мы в базу данных ничего не сереализируем. Туда наши обьекты мапяться. Для нас это делает тулинг(инфраструктура), например для базы данных это ОРМ тулы.
На другом сервере наши обьекты не оказываються. Там оказываються ДТО. Для ДТО у нас тоже есть тулинг типа AutoMapper.
MC>>Реализацию языка доменной модели. IB>"С точки зрения банальной эрудиции, не каждый индивидуум способено лояльно игнорировать тенденции..." далее по тексту. IB>Спорим я больше умных слов знаю? Реализация — это не ответственность.
Я же говорю читать надо, как я тебе еще могу сказать. Это стандарное понятиие в ДДД которое хрен оспориш. Если я тебе начну по-полочкам раскладывать ты опять отять буш выдергивать все из контекста и придираться к словам.
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, meowth, Вы писали:
M>>Здравствуйте, gandjustas, Вы писали:
ЛИ>>>>1) Главная задача архитектора меняется в зависимости от типа проекта и даже его фазы. Могу по собственному опыту сказать, что зачастую она заключается в минимизации затрат на сопровождение и развитие. Хорошо приготовленная RDM в этом смысле превосходит ADM, и Вы перечислили причины почему в той части, где говорите о преимуществах RDM; G>>>Ну это просто неверно. Как ни крути, а rich нарушает SRP, что негативно сказывается на стоиомости сопровождения. M>>Если не секрет, вам во сколько становилось в цифрах? Имхо без конкретного примера это только разговоры. G>В цифрах не могу, нету примера с жирной моделью и аналогичной ей стройной, чтобы сравнить. G>Первое на что можно обратить внимание — необходимость согласовывать изменения в DTO и доменных объектах.
Мы этим гордимся, у нас не бывает ситуаций когда поменял чето в доменной моделе а отвалиось гдето на ремо сервере. А все потому что DTO полностью развязаны. С свременными ИДЕ и тулингом потдерживать такую синхронизацию очень дешево.
G>Второе — достачно сложное создание произвольных выборок.
Уже говорили, выборки это не респонсибилити доменной модели, это респонсибилити репортинга.
Предположим что есть.
class Product{
}
class Image{
ProductId;
}
Для того чтобы получить флатен презентацию так или иначе придеться вводить промежуточное ДТО
ProductListItem{
Name
ImageSize,
ImageUrl
}
Решение и для рич моделей и для анмемичных идентичное.
Здравствуйте, IB, Вы писали:
IB>Ну, вы ребята тогда в какой-то альтернативной реальности живете, где объекты посредством страшного колдунства сами оказываются в базе, во внешнем файле, на другом сервере. Тут да, тут жирная модель возможно работает.. )
А в анемеичной модели с помощью колдовства сериализованные стандартными сериализатором объекты отлично понимают обработчики внешних файлов и другие сервера? Что с этими серверами становится при изменении модели?
Здравствуйте, Mike Chaliy, Вы писали:
MC>Здравствуйте, gandjustas, Вы писали:
ЛИ>>>3) Если имеют место большие объёмы данных, то лучше вообще не связываться с Domain Model. К счастью, большинство транзакционных сценариев не предполагает большого количества объектов, а значит можно в полной мере использовать преимущества RDM; G>>Еще раз? Какие премущества rich перед anemic? Бредятину типа "в ней больше ООП" не рассматриваем. G>>Покажите пример кода, где по rich гораздо удобнее anemic.
MC>Вот можем начать с этого.
MC>Rich MC>
MC>public void CreateOrder(number){
MC> var order = _orderFactory.Create(number);
MC> order.AddItem(product1, weight);
MC> order.AddItem(product2, weight);
MC> _orderRepository.Add(order);
MC>}
MC>
Ага, еще код AddItem покажи, и валидации.
Кстати в какой момент она выполняется?
MC>Anemic MC>
MC>public void CreateOrder(number){
MC> validateOrderNumber(number);
MC> var total = calcualteTotal(weight1, weight2);
MC> validateIfTotalAcceptable(total);
MC> var order = new Order(){Number = number, Total = total};
MC> var item1 = new Item(){OrderId = order.Id, ProductId = product1.Id, Weight = weight1};
MC> var item2 = new Item(){OrderId = order.Id, ProductId = product2.Id, Weight = weight2};
MC> _orderDAL.InsertOrder(order);
MC> _orderDAL.InsertOrderItem(item1);
MC> _orderDAL.InsertOrderItem(item2);
MC>}
MC>
Наверное имелось ввиду
public void CreateOrder(number)
{
var order = new Order(){Number = number, Total = calcualteTotal(weight1, weight2)};
var item1 = new Item(){Order = order, Product = product1, Weight = weight1};
var item2 = new Item(){Order = order, Product = product2, Weight = weight2};
_validationService.Validate(order);
_orderRepository.Add(order);
}
А вообще на лице денормализация. Надо бы еще объяснить зачем она нужна и почему бы не поддерживать целостность триггерами в БД, если денормализация нужна.
Кстати, что здесь Order.Total? Почему мы total проверяем при сохранении, а не там где действительно надо (при отправке например)?
Здравствуйте, gandjustas, Вы писали:
G>Здравствуйте, Mike Chaliy, Вы писали:
MC>>Здравствуйте, gandjustas, Вы писали:
ЛИ>>>>3) Если имеют место большие объёмы данных, то лучше вообще не связываться с Domain Model. К счастью, большинство транзакционных сценариев не предполагает большого количества объектов, а значит можно в полной мере использовать преимущества RDM; G>>>Еще раз? Какие премущества rich перед anemic? Бредятину типа "в ней больше ООП" не рассматриваем. G>>>Покажите пример кода, где по rich гораздо удобнее anemic.
MC>>Вот можем начать с этого.
MC>>Rich MC>>
MC>>public void CreateOrder(number){
MC>> var order = _orderFactory.Create(number);
MC>> order.AddItem(product1, weight);
MC>> order.AddItem(product2, weight);
MC>> _orderRepository.Add(order);
MC>>}
MC>>
G>Ага, еще код AddItem покажи, и валидации. G>Кстати в какой момент она выполняется?
Зачем, ты же просил где лушче. Так вот за счет того что у нас есть енкапсуляция, код бизнес процесов получаеться максимально читабельным.
MC>>Anemic MC>>
MC>>public void CreateOrder(number){
MC>> validateOrderNumber(number);
MC>> var total = calcualteTotal(weight1, weight2);
MC>> validateIfTotalAcceptable(total);
MC>> var order = new Order(){Number = number, Total = total};
MC>> var item1 = new Item(){OrderId = order.Id, ProductId = product1.Id, Weight = weight1};
MC>> var item2 = new Item(){OrderId = order.Id, ProductId = product2.Id, Weight = weight2};
MC>> _orderDAL.InsertOrder(order);
MC>> _orderDAL.InsertOrderItem(item1);
MC>> _orderDAL.InsertOrderItem(item2);
MC>>}
MC>>
G>Наверное имелось ввиду G>
G>public void CreateOrder(number)
G>{
G> var order = new Order(){Number = number, Total = calcualteTotal(weight1, weight2)};
G> var item1 = new Item(){Order = order, Product = product1, Weight = weight1};
G> var item2 = new Item(){Order = order, Product = product2, Weight = weight2};
G> _validationService.Validate(order);
G> _orderRepository.Add(order);
G>}
G>
нет мелось ввиду то что имелось,
1) ты отпарвил валидацию в конец, должно быть в начале, иначе возможны колизии, принцип фаил фаст знаеш? Обьяснить почему это проблема?
2) ты поубирал ИД поля. Но вы же с ИБ орете что вам надо Order — Item для одного отдела, TradingPeriod — Item для другого. Как же это вы свзянанные обьекты сможете представить для двух отделов. Как вы сможете собрать из этого ДТО для веб сервиса, если оно все в коде зареференшено.
3) ты поубирал ИД поля. Это обозначает что у вас юзаеться ОРМ и тоже может юзаться лейзи лоад.
4) ты нарушил СРП в вашем понимании, обьекты теперь хранят не тока данные обьекта, но и ссылки на другие обьекты.
G>А вообще на лице денормализация. Надо бы еще объяснить зачем она нужна и почему бы не поддерживать целостность триггерами в БД, если денормализация нужна.
Ты конкретней, ты где нашел денормализацию?
Ты про Тотал? Почитай про архитектуры финансовых систем. Там никогда агрегатные результаты не считаються динамически. Если один раз ордер продался по цене 20.00089 денег, то даже когда поменяеються требования к округлению он всеравно должно остаться 20.00089.
Плюс номрализация Тотала не потдаеться юнит тестированию.
G>Кстати, что здесь Order.Total? Почему мы total проверяем при сохранении, а не там где действительно надо (при отправке например)?
Потому что это бизнес процес который считает тотал. И этот же бизнес процес должен сказать если там что-то не так. Отправка это вообще не контекстаная операция. Нафига мне валидировать тотал если он уже посчитан и дефакто валидный?
В любом случае твой пример всеравно не читабельный. Попробуй его прочесть плаин текстом. Куча дублирования и мусора.
Здравствуйте, Mike Chaliy, Вы писали:
MC>Мы в базу данных ничего не сереализируем.
А что же вы в нее, простите, делаете?
MC>Туда наши обьекты мапяться.
В чем отличие знаешь?
MC> Для нас это делает тулинг(инфраструктура), например для базы данных это ОРМ тулы.
Как именно?
MC>На другом сервере наши обьекты не оказываються. Там оказываються ДТО. Для ДТО у нас тоже есть тулинг типа AutoMapper.
Как этот DTO получается из объекта?
MC> Это стандарное понятиие в ДДД которое хрен оспориш.
Если бы ты еще понятия к месту формулировал, бы ло бы вообще замечательно.
MC> Если я тебе начну по-полочкам раскладывать ты опять отять буш выдергивать все из контекста и придираться к словам.
Где я к словам придирался? Ты еще ни на один вопрос внятно не ответил...
Здравствуйте, Ziaw, Вы писали:
Z>А в анемеичной модели с помощью колдовства сериализованные стандартными сериализатором объекты отлично понимают обработчики внешних файлов и другие сервера?
Это ты к чему?
Z> Что с этими серверами становится при изменении модели?
Ты о чем?
Здравствуйте, Mike Chaliy, Вы писали:
MC>Мы этим гордимся,
Тем, что при изменении нужно поменять в четырех местах, а не в двух? Молодцы! =)
MC>у нас не бывает ситуаций когда поменял чето в доменной моделе а отвалиось гдето на ремо сервере.
Легко у вас такая ситуация бывает — в модели поле удалили, а в DTO забыли, а у клиента на это поле была критичная логика завязана. В запросе пришел NULL — клиент лег.
MC>С свременными ИДЕ и тулингом потдерживать такую синхронизацию очень дешево.
Просто признайтесь, что вы любите двойную работу.
MC>Уже говорили, выборки это не респонсибилити доменной модели, это респонсибилити репортинга.
Для тебя это возможно будет новостью, но 95% задач современного приложения — это репортинг.
Отсюда делаем вывод о применимости жирной модели.
MC>Решение и для рич моделей и для анмемичных идентичное.
Когда есть LINQ необходимость в промежуточных DTO отпадает, можно все по месту построить, для стройной модели, разумеется.
Здравствуйте, Mike Chaliy, Вы писали:
MC>Здравствуйте, gandjustas, Вы писали:
G>>Здравствуйте, meowth, Вы писали:
M>>>Здравствуйте, gandjustas, Вы писали:
ЛИ>>>>>1) Главная задача архитектора меняется в зависимости от типа проекта и даже его фазы. Могу по собственному опыту сказать, что зачастую она заключается в минимизации затрат на сопровождение и развитие. Хорошо приготовленная RDM в этом смысле превосходит ADM, и Вы перечислили причины почему в той части, где говорите о преимуществах RDM; G>>>>Ну это просто неверно. Как ни крути, а rich нарушает SRP, что негативно сказывается на стоиомости сопровождения. M>>>Если не секрет, вам во сколько становилось в цифрах? Имхо без конкретного примера это только разговоры. G>>В цифрах не могу, нету примера с жирной моделью и аналогичной ей стройной, чтобы сравнить. G>>Первое на что можно обратить внимание — необходимость согласовывать изменения в DTO и доменных объектах. MC>Мы этим гордимся, у нас не бывает ситуаций когда поменял чето в доменной моделе а отвалиось гдето на ремо сервере. А все потому что DTO полностью развязаны. С свременными ИДЕ и тулингом потдерживать такую синхронизацию очень дешево.
Ведь гораздо легче вообще не иметь такой синхронизации.
G>>Второе — достачно сложное создание произвольных выборок. MC>Уже говорили, выборки это не респонсибилити доменной модели, это респонсибилити репортинга.
Почему такая хорошая DDD заставляет выделять отдельное понятие репортинга? (на деле — любое отображение информации)
MC>Предположим что есть. MC>class Product{ MC>} MC>class Image{ MC> ProductId; MC>} MC>Для того чтобы получить флатен презентацию так или иначе придеться вводить промежуточное ДТО
MC>ProductListItem{ MC> Name MC> ImageSize, MC> ImageUrl MC>}
Суть не в DTO, а в способах его получения.
MC>Решение и для рич моделей и для анмемичных идентичное.
Ну покажи полное решение для такого случая в rich, учитывая что надо получать далеко не все все товары, там есть пейджинг, видимость, выборка по категории итп. Для каждого товара существует куча картинок и надо получить первую.
Здравствуйте, Mike Chaliy, Вы писали:
MC>Так вот за счет того что у нас есть енкапсуляция, код бизнес процесов получаеться максимально читабельным.
Код бизнес-процессов, за счет такой "енкапсуляции" получается малопредсказуемым и неочевидным.
MC>нет мелось ввиду то что имелось,
Тогда ты непонятно с чем споришь..
MC>В любом случае твой пример всеравно не читабельный.
Он гораздо понятнее чем твой.. )
Здравствуйте, IB, Вы писали:
IB>Здравствуйте, Mike Chaliy, Вы писали:
MC>> Для нас это делает тулинг(инфраструктура), например для базы данных это ОРМ тулы. IB>Как именно?
_productRepository.Add(product);
Тебя интересует как работает Add это к ОРМ тулу твоего выбора. В НХибирнейт это Session.Save(obj);
MC>>На другом сервере наши обьекты не оказываються. Там оказываються ДТО. Для ДТО у нас тоже есть тулинг типа AutoMapper. IB>Как этот DTO получается из объекта?
ProductDTO dto = Mapper.Map(product);
Тебя интересует как работает Mapэто к мапперу твоего выбора.
MC>> Это стандарное понятиие в ДДД которое хрен оспориш. IB>Если бы ты еще понятия к месту формулировал, бы ло бы вообще замечательно.
И что там не к месту? Именно реализация этого языка это и есть респонсибилити. Хранит данные, не хранит, реализованно это методами или чем-то другим — это детали реализации. А респонсибилити это реалзиация языка.
Нарпимер для респонсибилити обьекта ордер это реализация языка по работе с оредорм. Например: Вычиление Тотала, Добовление айтемов, Маркировка временных айтемов, Преход в состояние А.
Здравствуйте, Ziaw, Вы писали:
Z>Здравствуйте, IB, Вы писали:
IB>>Ну, вы ребята тогда в какой-то альтернативной реальности живете, где объекты посредством страшного колдунства сами оказываются в базе, во внешнем файле, на другом сервере. Тут да, тут жирная модель возможно работает.. )
Z>А в анемеичной модели с помощью колдовства сериализованные стандартными сериализатором объекты отлично понимают обработчики внешних файлов и другие сервера? Что с этими серверами становится при изменении модели?
Я уже спрашивал. Он считает что при изменении модели, публичный АПИ тоже должен поменяться .
Для них вообще поменять модель это что-то екстраординарное, обычно связанное с изменением модели данных, публичных АПИ, интерфесов пользователя и тому подобному...
Им не понять что такое поменять диометрально релейшеншип сущьностей и при этом не поменять ни хранилище и все вокруг .
Здравствуйте, IB, Вы писали:
IB>Инструмент — это инкапсуляция, и есть метрика правильности его применения.
Ну наконец — то.
GZ>>+-1 Только тогда это будет аналог Rich. IB>Нет. Самый близкий аналог Rich — это третий способ.
Вот ну офигенно оригинально. Разговор умного с суперумным.
— Модель плохая.
— Почему плохая? Вот же хорошее решение?
— Нет это не хорошее решение, потому что есть решение плохое.
— Почему нужно выбирать плохое решение?
— Потому что модель плохая, и для нее надо выбирать плохое решение.
Ну и что тут обсуждать?
GZ>>Только значительно хуже. Ибо в Rich, можно спрятать дополнительную информацию за интерфейсом и загружать по мере надобности. IB>Значительно лучше. Это не дополнительная информация, это всегда необходимая информация.
Это аггрегируемая информация. Ибо на физическом уровне, доступ управляется набором идентификаторов связанных с объектом. Для того, чтобы получить реальный ACL — нужно ее просчитать по контексту пользователя и по объекту. По каждому чиху просчитывать информацию? Гениальное решение. Предлагаю занести в аналы природы. А если еще учесть что в экспорте/импорте этой информация вообще не нужна. IB>Никто не собирается грузить родителя сразу, необходимая информация уже есть в дочернем, он самодостаточен, ему ничего не нужно. IB>Причем эта информация не является лишней, она необходима при каждой проверке доступа (и наверняка не только доступа, раз доступ на нее завязан).
Ты читаешь что я пишу?
GZ>>+1 Но проблема, что это надо передавать каждый раз в разных сценариях. IB>Это не проблема. Это как раз хорошо. Я явно в каждом сценарии понимаю, что нужно и явно это передаю.
Зачем???? Вот зачем тебе помнить чтобы солнце взошло, тебе нужно поднять сначало левый тумблем, а потом правый? Не проще ли на самом солнце кликнуть и не разбираться с проблемами бытия, орбит, и магнитных бурь.
IB>Причем забыть и не передать, я не могу — компилятор поправит.
Не поправит. У тебя интерфейс не изменяется, а только дополняется. IB>И явно передавая — четко понимаешь чего это стоит в каждом сценарии и каждый сценарий, при необходимости, ты можешь настроить отдельно, не трогая другие (например, в одном случае получая нужный объект из кеша, а в другом напрямую в обход всего, если это критично — инкапсуляция в действии (с)).
А вот зачем? Весь смысл Rich, это то что ты абстрагируешься от БД. Хочешь накормить кошку, просто дай ей еды. Ежели хочешь помнить о том чтобы кишочках все это переваривалось, то даже преждевременное вскрытие тебе не поможет. Ты об этом узнаешь только постфактум, когда кал из кошки пойдет. Точно также и в больших приложениях. Пока реальных данных нет, ты не можешь сказать что оно работает с той, или иной степенью эффективности.
GZ>>Таким образом, ты и связываешь разные места с контрактом ACLService.CanEdit. IB>А раньше они типа не были связаны, что ли?
Нет. В Rich — все места связаны с методом объекта. Объект и контекст пользователя, все что нужно для пользы дела. Все остальные проблемы, как зависимость от типа, можно решить в одном конкретном месте.
GZ>>Увеличиваешь cohesion. IB>Так этож хорошо.. Но на самом деле с когезией здесь ничего не происходит.
Звиняюсь, coupling.
GZ>>Со вторым ты вроде согласен. А вот первое, тебе покоя не дает. Несмотря на конкретный пример. IB>Конкретный пример показывает ровно обратное твоему утверждению, особенно если под ресурсоемкостью понимать стоимость дальнейшей поддержки, а не количество нажатий на клавиши для единоразового изменения логики CanEdit.
То, что можно изменить полиморфно поведение в одном месте существенно увеличивает поддержку? Абсолютно согласен. Ваще вопросов не возникает.
GZ>>Тады ACLService придется понимать с каким именно объектом он имеет дело. IB>Ровно в той же степени, что и для Rich.
В Rich — строго наоборот. Объект решает как ему проверяться. Это большая разница.
GZ>>Нет. Это может быть список объектов которые можно редактировать. А может быть и список идентификаторов объектов которые можно редактировать. IB>Из базы все равно приезжает список объектов, а не идентификаторов.
С чего ты решил?