Здравствуйте, Sharov, Вы писали:
S>Здравствуйте, gandjustas, Вы писали:
S>>>Да, вполне согласен. Не исключаю, что все эти моменты под одну крышуметодологию запихнули и все. Как-то так оно и есть.
S>>>Потом решили развивать идею дальше, и появились тактические паттерны и тп.
G>>См историю, тактические паттерны появились в начале. Все описал фаулер еще до эванса. Вся суть ДДД с самого начала — натягивание философии на паттерны. Когда модным стал CQRS — он появился в книгах DDD. Когда стали модными микросервисы — они тоже появились в книгах по DDD.
S>Может быть, но ДДД очень любят применять при распилах монолита на микросервисы. Работал в таком проекте.
S>>>Ну тактические все-таки что-то новое, все эти agg root, transaction script, entity, values. А так да, взяли отовсюду понемногу.
Абсолютно не связанные между собой вещи. Микросервисы ничего не говорят об архитектуре внутри сервиса.
G>>Это фаулер описал, до DDD
S>Ну а Эванс добавил стратегические паттерны и превратил все это методологию. Что называется стоял на плечах гигантов.
Как я и написал ниже он добавил философию.
S>>>Какой сервис в компании не беру, везде есть Repository. Это уже ~Dal по сути.
G>>Мода — она такая, везде ропозитарии, хотя они не нужны.
S>Соглашусь. Ну, кстати, и ООП тоже своего рода мода.
На ооп мода была в середине девяностых — середине нулевых. Мода прям адская, все что не ООП — было "фу". На волне этой моды ДДД и появилось.
Потом микрософт нанял Эрика Мейера, который до этого Хаскелем занимался и он всех покусал функциональщиной, а в 2011 вышел стандарт с++11, в ктором вся стандартная библиотека была функциональной.
На той волне даже JS голову поднял, в нем давно было то, что в мире ФП ценилось.
S>>>Вкусовщина, типа нраится\ не нраится. Могли бы perl для веба взять. Никаких экспериментов по написанию веб приложения на пхп, а потом на C# не было же?
G>>Книг по perl было на прядок меньше, на фоне C++\java\C# и остальных.
S>Странно, учитывая что он на 20 лет появился раньше. А на питон почему не смотрели, вроде для него уже были фреймоврки для веба?
Возраст языка не показатель популярности. в 2005 на полках книг по C# и Java было одинаково, даже по C++ было меньше, хотя он старше. А по перлу если одна попадалась на полке, то лежала там несколько лет.
S>>>1) Каким боком это к дискуссии?
S>>>2) Речь же шла про инвариант класса, а не ДДДшное исполнение чего-то. Инвариант класса и ДДД противоречат где-то?
G>>Как обычно попытка решить нетривиальную задачу проектирования с помощью DDD приводит или к "это другое" или к CQRS и эвентсорсингу.
S>При чем здеьс обеспечение инварианта и ДДД?
Видимо это никак не связанные вещи
S>>>Она(бд) эти данные потом в память себе загоняет и работает с ними. Так что в памяти и работает.
G>>Тем не менее "объектами" там не пахнет.
S>Объектами самой бд, типа строки\колонки\талбицы и т.п.
У слова "объект" в программировании есть вполне конкретное значение. строки\колонки\талбицы не являются объектами с точки зрения работы с БД.
S>>>Как?
G>>Запросом на уровне базы, который писал выше. Из базы на уровень приложения ничего не попадает.
S>А ответ от базы где и кем анализируется, для чего запрос-то делать, если ответ никуда не попадет, точнее не попадет в приложение?
Этот запрос меняет состояние в БД. Можно проанализировать его успешность, если что-то пошло не так, то кинуть исключение. Но обсуждению выше отношения не имеет.
G>>>>Очередное мнение, которое подкреплено примерно ничем?
S>>>Чем хуже вашего мнения?
G>>Тем что я не пытаюсь доказать полезность и применимость DDD.
S>Я пытаюсь настоять на его полезности хотя бы в рамках распила монолита на микросервисы.
Ок, давай примеры чем именно ДДД помогает. А еще было бы неплохо описать "механизм действия", а то может ДДД не при чем.
Или нам поверить что помогает потому что кто-то сказал?
G>>Бремя доказательство обычно возлагается на того кто утверждает, пока он не представил объективные аргументы.
S>У меня их нету
Ок, значит просто вера
S>выбор языка ОПП C# вы тоже особо не доказывали, а просто вкусовщина или книжек мало.
мне кажется ты просто проигнорировал все что я написал или просто контекст закончился и старые сообщения не учитываются при генерации новых ответов.
S>>>ДДД утв. что если вы правильно поняли бизнес и модель предметной области, то все должно взлететь. Делайте так и все получится.
G>>Если есть контрпример, то можно считать утверждение ложным?
S>Давайте разберем контрпример. Хотя думаю, что мое утверждение выше было чрезмерно сильным. Возможно ДДД ничего такого не утверждает.
Допустим разрабатывается система, аля трекер. Заказчик хочет возможность ограничить количество задач для пользователя.
Будут две сущности: Issue и User, связанные много-к-одному.
У Issue есть метод AssignTo, которому надо передать User или его Id, чтобы связать. И надо как-то гарантировать что выполняется условие, что для одного User назначено не более трех Issue/
Какую реализацию нам диктует прагматичный подход (ПП):
Прямо в контроллере, в одной транзакции (!) сделать два запроса:
update issues set user_id = @userid where id = @id;
select count(*)from issues where user_id = @userid
Для PG и других баз с оптимистичными блокировками нужен уровень изоляции serializable и повтор запросов при ошибке, а для SQL Server без RCS и MySQL (и других блокировочников) достаточно read committed
Реализация на C# для postgres может выглядеть так:
var db = ctx.Database;
await db.CreateExecutionStrategy().ExecuteAsync(async ct =>
{
await using var t = await db.BeginTransactionAsync(System.Data.IsolationLevel.Serializable, ct);
await ctx.Issues.Where(i => i.Id == id).ExecuteUpdateAsync(s => s.SetProperty(x => x.UserId, userId), ct);
if (await ctx.Issues.CountAsync(x => x.UserId == userId, ct) > 3) throw new Exception("Auchtung");
}, ct);
С этой же задачей я пошел в рекомендованный тобой чат, попросил показать пример DDD. три дня срачей, рассказов что я не умею требования анализировать, что задача вообще нереальная и не надо её решать итд.
Самое лучшее что один из участников написал пайтоне
class User(DomainEntity[UserId]):
def __init__(self, entity_id: UserId, issue_count: int) -> None:
super().__init__(entity_id)
self._issue_count = issue_count
def take_issue(self) -> None:
MAX_ISSUE_COUNT = 3
self._issue_count += 1
if self._issue_count > MAX_ISSUE_COUNT:
raise TooManyIssues
class Issue(DomainEntity[IssueId]):
def __init__(self, entity_id: IssueId, metadata: str, user_id: UserId | None):
super().__init__(entity_id)
self._metadata = metadata
self._user_id = user_id
def assign_to(self, user: User) -> None:
if self._user_id:
raise IssueIsAlreadyAssigned
user.take_issue()
self._user_id = user.entity_id
То есть прделагают два агрегата. User хранит счетчик issue. Причем в реальности такая логика будет размазана по разным файлам.
1) Во первых код тупо не полный, так как кроме увеличения при назначении надо еще уменьшать при переназначении.
2) Как будет обеспечиваться изоляция транзакций непонятно, этого кода также нет.
А теперь представим что программа у нас развивается и требования чуть усложнились: теперь надо считать не все Issue, а только в нужном статусе.
В варианте на C# добавить фильтр и код проверки вызывать как в методе назначения задачи, так и при смене статуса на нужный.
Что делать в варианте на пайтоне — даже боюсь представить.
Получается что сделали по ДДД максимально хорошо насколько люди поняли ДДД, а получилось раздутое нерасширяемое и скорее всего ненадежное говно.
S>>>Ну ведь фигней занимаетесь, не будете переписывать огромный софт под 1млн. без ДДД. Ну к чему эта бравада?
S>>>Какое-то детсадовское взятие на слабо. Не серьезно.
G>>Как тогда доказать что-то про ДДД?
S>Не знаю, методом проб и ошибок.
А что надо пробовать? Я и предлагаю попробовать две программы с эквивалентными функциями сравнить.
S>>>Я говорил, что он не плох, если кому-то не нравится. Ровно в этом моя позиция. Научный подход в ИТ вещь такая себе -- почему написали на C#, когда можно было на С++ или вообще на Си? Это бред и демагогия, не нравится, не пользуйтесь. Я вот избирательно что-то для себя в ДДД подчеркнул и мне
G>>хорош, никакого научного подхода не надо.
G>>Звучит как вера. Вам верить никто не мешает, но нести свою веру другим в целом противопоказано.
S>Блин, ну как тогда любая технология взлетает, если в нее по сути по началу верять пару человек, если вообще не один? При таком подходе никакого ООП бы не было.
Серьезно считаешь что ООП родилось из веры?
ООП родилось из решения частных задач, а именно моделирования поведения в агентной системе. Внезапно первый ОО-язык это была в первую очередь агентная система.
Авторы ООП никуда ООП не продвигали. Последователи сами захотели включить его в свои языки, причем сильно по разному.
От появления ООП до первых популярных языков прошло почти 20 лет.
Больше всех ООП популяризировал C++, потому что он по сути добавлял новые фичи в адски популярный тогда С. Возможно если бы не Страуструп то такого хайпа и не случилось бы.
Популярность ООП это скорее череда совпадений и неплохой изначальной идем, которую специально никто не форсил.
А с DDD ровно обратная картина.
S>>>Блин, ну какой научный подход у agile, рефакторинга и solid?
G>>Есть конечно, исследования всякие.
G>>Насчет solid не знаю, про agile и рефакторинг находил.
S>Ну вот про научно доказанную пользу agile я бы почитал.
Да там банальное исследование было: опрос какие практики применяют и считали корреляцию с "успешностью" проектов. Как успешность считали уже не помню.