Re: Как определить где размещать бизнес-логику
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.06.21 14:04
Оценка: 76 (2)
Здравствуйте, Nikita Lyapin, Вы писали:

NL>Привет всем!


NL>Часто возникают обсуждения о том где размещать бизнес-логику приложения. В итоге я собрался силами, систематизировал свои знания по этому вопрос и написал статью. Здесь

NL>По большому счету Фаулер все написал, но я взял на себя смелость его дополнить. Я прав? Или ошибаюсь? Хотелось бы обсудить с сообществом.

Я тепрь тоже подавлю авторитетом, предложив прочитать серию статей Эрика Липперта (небезызвестный человек) про моделирование предмтной области с помощью классов и методов

https://ericlippert.com/2015/04/27/wizards-and-warriors-part-one/
https://ericlippert.com/2015/04/30/wizards-and-warriors-part-two/
https://ericlippert.com/2015/05/04/wizards-and-warriors-part-three/
https://ericlippert.com/2015/05/07/wizards-and-warriors-part-four/
https://ericlippert.com/2015/05/11/wizards-and-warriors-part-five/

Они изначально берет задачу моедлирования, когда нет внешних хранилищ, пользовательных запросов и затрат на вытагивание данных.
Казалось бы идеальная ситуация для "domain model"

Небольшим усложнением "бизнес-правил" он добивается того, что наивный ООП-код на C# перестает описывать павила достаточно внятно без лишнего количества технических деталей.

В итоге приходит к выводу, который я процитирю:

The fundamental problem is my initial assumption that the business rules of the system are to be expressed by writing code inside methods associated with classes in the business domain

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

Далее липперт выводит то, что называется anemic model

Now all our previous problems fade away. A player has a weapon, great, that’s fine, we’ll make a Player class with a property of type Weapon. That code makes no attempt to try to represent that a wizard can only wield a staff or a dagger; all that code does is keep track of game state, because state is its concern.


Далее он описывает архитектуру, которую фаулер назвал бы transaction script

Then we make a Command object called Wield that takes two game state objects, a Player and a Weapon. When the user issues a command to the system “this wizard should wield that sword”, then that command is evaluated in the context of a set of Rules, which produces a sequence of Effects.


Бизнес-правила он предлагает описывать классам-стратегиями (так же, как показывал Синклер).

Всем рекомендую почитать эту серию статей для очистки мозга.
Отредактировано 10.06.2021 14:05 gandjustas . Предыдущая версия .
Re[3]: Как определить где размещать бизнес-логику
От: Sinclair Россия https://github.com/evilguest/
Дата: 09.06.21 12:00
Оценка: +2
Здравствуйте, Nikita Lyapin, Вы писали:

NL>Парадигмы не устаревают. Вы можете использовать все самые новомодные библиотеки, но при этом хорошо бы озадачиться вопросом в какой парадигме вы пишете. Если вы пишите на ООП языке вроде C# и при этом у вас везде static методы да и только — у вас не используется парадигма ООП. Дело в том, что фреймворки и ОРМ по своей природе накладывают ограничения на то как их можно использовать.

Нет, дело в том, что Фаулер устарел. Вопросом о "парадигме" озадачиваться не надо. "Парадигмы" — это для слабых духом, кто пока неспособен самостоятельно отличить хороший код от плохого.
ООП само по себе не хорошо и не плохо, как и ФП, и процедурное программирование. Хорошим или плохим является конкретный код.
Например,фреймворк, который позволяет уменьшить количество кода, которое нужно написать программисту — это хороший фреймворк.

Ещё раз попробую объяснить сложную вещь: transaction script совершенно не обязан быть прибит гвоздями к процедурному подходу.
Transaction script характерен тем, что в нём программа (или сервер приложений, если мы говорим о трёхзвенке) порождают набор инструкций для DBMS.
Фаулеру просто не пришло в голову, что код, порождающий этот набор инструкций, вовсе не обязан быть в процедурах (или в static методах).
Я могу порождать его вполне себе ООП-кодом. Например, использую паттерн Стратегия для того, чтобы добавить код расчёта скидок в мой код обработки заказа.
При этом и тот и другой код не будет собственно ничего считать. Просто в батч будут добавляться различные SQL-стейтменты.
И это — гораздо более рациональный способ использования ООП для работы с данными, чем материализация "заказов", "позиций заказов", и "правил начисления скидок" в виде настоящих объектов, а затем мучительное сохранение их обратно в базу.

NL>Linq2Db занял свою нишу. Это типизированный SQL по факту. Рассуждать о том, что хранимые процедуры больше относятся к ООП, чем к процедурам. Ну странно как-то... Ведь разница между хранимой процедурой и кодом на Linq2Db в сущности только в типизации и все...

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

NL>В идеале для реализации ООП подхода в полной мере нужно получить набор доменных обьектов с методами и все. Т.е. бизнес логика должна быть выражена на чистом языке программирования без примесей технических деталий. Бизнес правила и так слишком сложны. Код больше читают, чем пишут.

Нет. У вас неверное представление об идеале. В нормальном решении задачи автоматизации никаких доменных объектов с методами нет. Есть реляционная модель, описывающая факты, и бизнес-модель, описывающая правила трансформации фактов.
Наиболее естественный способ описывать трансформации фактов — язык SQL. В нём можно напрямую записать сложные вещи типа "после проведения приходной накладной количества складских позиций увеличиваются на количества соответствующих товарных позиций в накладной", не опускаясь на уровень циклов и ветвлений.

А вот порождать этот SQL нужно объектно-ориентированным способом, т.к. сам SQL к декомпозиции приспособлен очень плохо. Он спроектирован для одноразовых запросов, которые в командной строке набирает оператор.
linq2db — гораздо больше, чем "типизированный SQL", хотя и этого уже очень много — в большинстве сред нет и его.
То, что он умеет делать — как раз декомпозировать порождение SQL.
Без помощи linq2db невозможно сделать ничего похожего на
IQueryable<T> CheckPermissions<T>(IQueryable<T> items, User user) 
  where T: ISecurable => 
    from i in items 
    from p in db.Permissions.Where(pr=>pr.ObjectId == i.Id && pr.UserId == user.Id)
     select i;

Это позволяет не заниматься написанием однообразных процедур (хранимых или традиционных) для каждого из десятка-двух видов таблиц. При этом — 100% контроль компилятора за порождением кода. И можно централизованным образом менять правила Row-Level Security при необходимости:
IQueryable<T> CheckPermissions<T>(IQueryable<T> items, User user) 
  where T: ISecurable => 
    user.IsInRole(KnownRoles.SuperAdmin) 
    ? items
    : from i in items 
      from p in db.Permissions.Where(pr=>pr.ObjectId == i.Id && pr.UserId == user.Id)
       select i;

Подобный подход позволяет бить логику на кусочки — предположим, CheckPermissions() у меня входит в некоторый интерфейс IAccessPolicy. Я параметризую свой код либо типом, который реализует этот интерфейс, либо экземпляром этого типа:
public Vehicle ReserveTransportation(User requestor, int numberOfPersons, IAccessPolicy accessPolicy)
{
   var vehicles = accessPolicy.CheckPermissions(db.CompanyVehicles, requestor);
   vehicles = from v in vehicles where v.Capacity >= numberOfPersons && v.IsAvailable orderby v.Cost;
   return vehicles.First(); 
}

Вот вам пример transaction script, который построен по принципу ООП. На каждый реквест, который выставлен наружу, есть отдельная "процедура". Но внутри эта процедура собирает конкретную логику из многих кусочков. Её порождает некоторый объект какого-то класса, который пользуется всеми методами ООП и паттернами проектирования — наследование, перегрузки, шаблонный метод, стратегия, фасад, you name it.
Ничего подобного Фаулер придумать не смог; в основном потому, что в его время об этом мало кто задумывался. Ну, и потому, что реализация некоторых аспектов такого подхода на доисторических языках требует нечеловеческих усилий.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: Как определить где размещать бизнес-логику
От: Nikita Lyapin Россия https://architecture-cleaning.ru/
Дата: 10.06.21 09:20
Оценка: +1 -1
Да, это все очень важно. Меня лишь удивило отсутсвие понимание подтекста вопроса о тестах. Ну или не желание на него отвечать прямо в виду невыгодности позиции.
Но давайте подытожим, что я вижу:
1. Тестов либо нет, либо они делаются QA ручками без всяких CI CD. Либо они интеграционные и медленные. И доля интеграционных тестов — большинство. Все это работает и так делать можно. Но если проект у вас не крупный. И даже не средний. Если тесты выполняются руками, то в крупном проекте регрес будет проходить за неделю. Правите в одном месте — опять полный регрес. Если интеграционные тесты — в крупном проекте их тысячи. Должны быть быстрыми для комфортной разработки.
2. Обьем кода от ООП (ОРМ и обвесов) не растет линейно. Т.е. да, вы в начале добавляете 200 строк кода. Но по мере роста вы не добавляете по 200 строк на каждое бизнес-правило. Наоборот. Дополнительный оверхед достигается за счет мапинга, сервисов и репозиториев. Далее вы уже используете готовую инфраструктуру. Отсюда вывод — для маленького проекта не имеет смысла. Дла большого — имеет.
3. Все такпи статичекие переменные — это как раз признак процедурности. Ну или в любом случае затрудненной сопровождаемости кода. Командная работа, поять же сложный и комплексный домен, который невозомжно уместить в голове — все это сразу мимо. И опять — для маленького проекта все окей.
Итого, стиль который вы описали отлично подходит для небольшого по обьему проекта. Со сложным — будут проблемы. Единственное, что тут нужно учесть — это микросервисы. С их приходом каждый конкретный микросервис в целом простой. И там вполне можно так писать. И я бы даже сказал, что иногда нужно так и только так.
Вот такая у меня позиция.
Re[13]: видео vs текст
От: Sinclair Россия https://github.com/evilguest/
Дата: 12.06.21 03:32
Оценка: +2
Здравствуйте, Sharov, Вы писали:
S>У меня ровно обратный опыт, если есть скорость 2х. А 2х читать я не умею. При прочих равных предпочту видео.
Простите, я в это не верю. Можно просто взять текст из любого выступления, и засечь время на его чтение про себя. Потом сравнить с временем по ролику.
2х — это всё ещё очень медленно.
Плюс крайнее неудобство навигации — в тексте, если я встречаю непонятное место, я тут же возвращаюсь назад и перечитываю, сопоставляя и сравнивая. В видео прыгать по +- 10 секунд — это лотерея.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Как определить где размещать бизнес-логику
От: Sinclair Россия https://github.com/evilguest/
Дата: 05.06.21 02:23
Оценка: +1
Здравствуйте, Nikita Lyapin, Вы писали:

NL>По большому счету Фаулер все написал, но я взял на себя смелость его дополнить. Я прав? Или ошибаюсь? Хотелось бы обсудить с сообществом.

Фаулер устарел на 20 лет. Прямо в этом же форуме уже были подробные обсуждения его заблуждений. Коротко о главном:
1. Transaction Script у Фаулера почему-то прибит гвоздями к процедурному подходу. Даже двадцать лет назад ничто не мешало порождать скрипт объектно-ориентированным способом.
Это сразу же убирает обозначенные Фаулером недостатки.
2. В современном .Net есть нормальные ORM, которые позволяют вообще не считать код по обмену данными между базой и приложением частью приложения. В Java тоже всё гораздо лучше, чем во времена Фаулера, хотя и отстаёт на одно-два поколения от linq2db.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: Как определить где размещать бизнес-логику
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 09.06.21 14:01
Оценка: +1
Здравствуйте, Nikita Lyapin, Вы писали:

NL>В идеале для реализации ООП подхода в полной мере нужно получить набор доменных обьектов с методами и все.

Почему существует таое мнение, что ООП = доменная модель, а отсутстие доменной модели это не ООП.

Вся разница заключается в том, какой вариант выбрать:
order.Process()

или
orderProcessor.Process(order)


При этом ВСЕДА внтури первого варианта вызывается второй.

NL>Т.е. бизнес логика должна быть выражена на чистом языке программирования без примесей технических деталий.

Меня всегда умиляла наивность подобных утверждений.
Вот есть простое правило — нельзя продать два билета на одно место. Мы делаем систему для продажи билетов в театр в кассах по всему городу.

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


NL>Бизнес правила и так слишком сложны. Код больше читают, чем пишут.

Многие "правила" являются не инвариантами, а пред- или пост- условиями для опредеенных тразакций. В сложных случаях доходит до того, что у разных транзакций предусловия будут противоречить друг другу и виде "бизнес-правил модели" их не запишешь. Поэтому чем сложнее система, тем лучше подойдет архитектура transaction script, безотносительно того какими средствами генерируются запросы к базе данных.
Re[10]: Как определить где размещать бизнес-логику
От: Nikita Lyapin Россия https://architecture-cleaning.ru/
Дата: 10.06.21 11:41
Оценка: :)
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Nikita Lyapin, Вы писали:


S>Давайте так — покажите код, который реализует вот это простое бизнес-правило "сотруднику предоставляется самый дешёвый автомобиль среди тех, которые ему можно использовать".

S>С тестами.
S>Может быть, действительно, linq будет плохим ответом на подобную задачу.

Я могу вам порекомендовать курс
Там все подробно разбирается. Если у меня будет время — напишу вам пример, который вы хотите. Но чуть позже. Пока времени нет.
Re[9]: Как определить где размещать бизнес-логику
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.06.21 12:31
Оценка: +1
Здравствуйте, Nikita Lyapin, Вы писали:

NL>Здравствуйте, gandjustas, Вы писали:


G>>Здравствуйте, Nikita Lyapin, Вы писали:


NL>>>Странный вопрос. Даже очень. Тестировать я хочу бизнес-правила. Например, что при задании определенных пермишенов мне только заданные items отоброжаются. И да, Linq2Db мне тестировать ну совсем не хочется. И как это реализовать в вашем примере без теста Linq2Db? С статическими то переменными в коде... выкрутиться можно. Но будет такое себе зрелище. Просто интересно как вы это решаете.


G>>Я не знаю как там у linq2db, но у EF вполне можно инмемори контекст для тестов сделать. И в конце концов что мешает тесты запускать на базе sqlite например?


NL>Решение с sqllite — костыль. Давайте себе честно в этом признаемся. Разница с постгресом будет где-то в два раза быстрее. Настоящие true unit тесты будут в тысячи раз быстрее.


Давай на конкретных примерах:
1) Что нужно чтобы протестировать правило "нельзя продавать два билета на одно место"? Как проверить без базы? Какие будут true unit тесты?
2) В каких конкретно примерах синклена нужна база для тестирования? Ты же в курсе что IQueryable можно получить из IEnumerable и на нем можно тестировать все linq-запросы?



NL>Ну вот вы пишите с EF — да уже лучше. Немно сдвинули нашу кривую затратности (см график из статьи). Но опять же не всегда имеет смысл. Для простейшего проекта где две таблицы и все — достаточно дапера. Дазем все уложнять. И интеграционные тесты там вполне могут жить, потому что их не много и написать их легко.

Хорошо, согласились уже что для простого приложения EF достаточно. Осталось найти границу где EF становится недостаточно и обязательно надо городить что-то свое.
На практике граница двигается вперед в зависимости от навыка программиста использования Linq и возможности базы.
Более того, там где возможности большинства linq-провайдеров кончаются, "доменная модель" не помогает от слова совсем.
Re[11]: Как определить где размещать бизнес-логику
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.06.21 13:04
Оценка: -1
Здравствуйте, Nikita Lyapin, Вы писали:
NL>Я могу вам порекомендовать курс
NL>Там все подробно разбирается. Если у меня будет время — напишу вам пример, который вы хотите. Но чуть позже. Пока времени нет.
Ну, я вот этих статей и курсов видел в ассортименте. Пока что — ничего интересного.
Самое интересное, что видел (но так и не изучил глубоко) — это использование для бизнес-логики ФП на F#. Там при помощи алгебраических типов данных довольно круто описываются ограничения доменной модели.

Смотреть видео — самый бездарный способ потратить время разработчика. Я читаю текст примерно в 5-10 раз быстрее, чем закадровый голос в этом курсе.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Как определить где размещать бизнес-логику
От: Nikita Lyapin Россия https://architecture-cleaning.ru/
Дата: 30.04.21 10:50
Оценка:
Привет всем!

Часто возникают обсуждения о том где размещать бизнес-логику приложения. В итоге я собрался силами, систематизировал свои знания по этому вопрос и написал статью. Здесь
По большому счету Фаулер все написал, но я взял на себя смелость его дополнить. Я прав? Или ошибаюсь? Хотелось бы обсудить с сообществом.
Re: Как определить где размещать бизнес-логику
От: scf  
Дата: 30.04.21 11:07
Оценка:
Здравствуйте, Nikita Lyapin, Вы писали:

NL>По большому счету Фаулер все написал, но я взял на себя смелость его дополнить. Я прав? Или ошибаюсь? Хотелось бы обсудить с сообществом.


Похоже, надо перечитать книгу. Совершенно непонятно, что мешает использовать transaction script с domain model, стараясь по возможности совмещать модельные классы с table module.

Про стоимость реализации тоже сомнительно — большие системы тяготеют скорее к процедурному подходу, чем к ООП, даже если состоят из объектов.
Отредактировано 30.04.2021 11:08 scf . Предыдущая версия .
Re[2]: Как определить где размещать бизнес-логику
От: Nikita Lyapin Россия https://architecture-cleaning.ru/
Дата: 30.04.21 14:57
Оценка:
Здравствуйте, scf, Вы писали:

scf>Здравствуйте, Nikita Lyapin, Вы писали:


NL>>По большому счету Фаулер все написал, но я взял на себя смелость его дополнить. Я прав? Или ошибаюсь? Хотелось бы обсудить с сообществом.


scf>Похоже, надо перечитать книгу. Совершенно непонятно, что мешает использовать transaction script с domain model, стараясь по возможности совмещать модельные классы с table module.


Вопрос скорее в соотношении. На практике — да, часто приходится для перфоманса делать что-то на чистом SQL. Но это даже не 15% от общего числа кода.

scf>Про стоимость реализации тоже сомнительно — большие системы тяготеют скорее к процедурному подходу, чем к ООП, даже если состоят из объектов.

Но вроде бы ООП со сложностью борется лучше процедурного подхода. Нет? Про функциональный подход, конечно помню. Но мы ведь о процедурном говорим? Если да, то не соглашусь... Но свою позицию не навязываю.
Re: Как определить где размещать бизнес-логику
От: varenikAA  
Дата: 01.05.21 09:42
Оценка:
Здравствуйте, Nikita Lyapin, Вы писали:

NL>Привет всем!


NL>Часто возникают обсуждения о том где размещать бизнес-логику приложения. В итоге я собрался силами, систематизировал свои знания по этому вопрос и написал статью. Здесь

NL>По большому счету Фаулер все написал, но я взял на себя смелость его дополнить. Я прав? Или ошибаюсь? Хотелось бы обсудить с сообществом.

Бизнес-логика это своего рода домен-специфичный калькулятор, поэтому где размещать тут все просто — в отдельном модуле.
Быть может все определяют конкретные условия в которых рождается и развивается проект?
Вот например, для чего вводят интерфейс сервиса?
Для возможнсти тестирования/нескольких реализаций/разделения функционала.
Тестирование предполагает наличие для этого времени.
Несколько реализаций быть может, но редко, чаще используется базовый класс а все наследники реализуют одну логику, особенно если это бизнес-логика.
Разделить функционал имеет смысл только при разделении компонентов. В монолитном приложении смысла в создании query-command разделения нет.
Опять же это возможно и оправдано при наличии времени и людей. Если проект разрабатывается в одного то не вижу смысла.
Другой аспект это возможности ЯП по созданию нормальной архитектуры.
Позволю встречный вопрос, как реализовать обработку ошибок try|catch. Пихать в каждый метод. Реализовать прокси. Использовать Функцию типа TryWithDo(() => ok(),() => fail(), () => fin())?
В каких ЯП какие есть средства/методы очистить бизнес-логику от инфрастуктурного кода?
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[2]: Как определить где размещать бизнес-логику
От: Nikita Lyapin Россия https://architecture-cleaning.ru/
Дата: 09.06.21 10:56
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Nikita Lyapin, Вы писали:


NL>>По большому счету Фаулер все написал, но я взял на себя смелость его дополнить. Я прав? Или ошибаюсь? Хотелось бы обсудить с сообществом.

S>Фаулер устарел на 20 лет. Прямо в этом же форуме уже были подробные обсуждения его заблуждений. Коротко о главном:
S>1. Transaction Script у Фаулера почему-то прибит гвоздями к процедурному подходу. Даже двадцать лет назад ничто не мешало порождать скрипт объектно-ориентированным способом.
S>Это сразу же убирает обозначенные Фаулером недостатки.

Парадигмы не устаревают. Вы можете использовать все самые новомодные библиотеки, но при этом хорошо бы озадачиться вопросом в какой парадигме вы пишете. Если вы пишите на ООП языке вроде C# и при этом у вас везде static методы да и только — у вас не используется парадигма ООП. Дело в том, что фреймворки и ОРМ по своей природе накладывают ограничения на то как их можно использовать.

S>2. В современном .Net есть нормальные ORM, которые позволяют вообще не считать код по обмену данными между базой и приложением частью приложения. В Java тоже всё гораздо лучше, чем во времена Фаулера, хотя и отстаёт на одно-два поколения от linq2db.

Linq2Db занял свою нишу. Это типизированный SQL по факту. Рассуждать о том, что хранимые процедуры больше относятся к ООП, чем к процедурам. Ну странно как-то... Ведь разница между хранимой процедурой и кодом на Linq2Db в сущности только в типизации и все...

В идеале для реализации ООП подхода в полной мере нужно получить набор доменных обьектов с методами и все. Т.е. бизнес логика должна быть выражена на чистом языке программирования без примесей технических деталий. Бизнес правила и так слишком сложны. Код больше читают, чем пишут.
Re[4]: Как определить где размещать бизнес-логику
От: Nikita Lyapin Россия https://architecture-cleaning.ru/
Дата: 09.06.21 18:25
Оценка:
Здравствуйте, Sinclair, Вы писали:

NL>>В идеале для реализации ООП подхода в полной мере нужно получить набор доменных обьектов с методами и все. Т.е. бизнес логика должна быть выражена на чистом языке программирования без примесей технических деталий. Бизнес правила и так слишком сложны. Код больше читают, чем пишут.

S>Нет. У вас неверное представление об идеале. В нормальном решении задачи автоматизации никаких доменных объектов с методами нет. Есть реляционная модель, описывающая факты, и бизнес-модель, описывающая правила трансформации фактов.
S>Наиболее естественный способ описывать трансформации фактов — язык SQL. В нём можно напрямую записать сложные вещи типа "после проведения приходной накладной количества складских позиций увеличиваются на количества соответствующих товарных позиций в накладной", не опускаясь на уровень циклов и ветвлений.

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

S>linq2db — гораздо больше, чем "типизированный SQL", хотя и этого уже очень много — в большинстве сред нет и его.
S>То, что он умеет делать — как раз декомпозировать порождение SQL.
S>Без помощи linq2db невозможно сделать ничего похожего на
S>
S>IQueryable<T> CheckPermissions<T>(IQueryable<T> items, User user) 
S>  where T: ISecurable => 
S>    from i in items 
S>    from p in db.Permissions.Where(pr=>pr.ObjectId == i.Id && pr.UserId == user.Id)
S>     select i;
S>

S>Это позволяет не заниматься написанием однообразных процедур (хранимых или традиционных) для каждого из десятка-двух видов таблиц. При этом — 100% контроль компилятора за порождением кода. И можно централизованным образом менять правила Row-Level Security при необходимости:
S>
S>IQueryable<T> CheckPermissions<T>(IQueryable<T> items, User user) 
S>  where T: ISecurable => 
S>    user.IsInRole(KnownRoles.SuperAdmin) 
S>    ? items
S>    : from i in items 
S>      from p in db.Permissions.Where(pr=>pr.ObjectId == i.Id && pr.UserId == user.Id)
S>       select i;
S>

S>Подобный подход позволяет бить логику на кусочки — предположим, CheckPermissions() у меня входит в некоторый интерфейс IAccessPolicy. Я параметризую свой код либо типом, который реализует этот интерфейс, либо экземпляром этого типа:
S>
S>public Vehicle ReserveTransportation(User requestor, int numberOfPersons, IAccessPolicy accessPolicy)
S>{
S>   var vehicles = accessPolicy.CheckPermissions(db.CompanyVehicles, requestor);
S>   vehicles = from v in vehicles where v.Capacity >= numberOfPersons && v.IsAvailable orderby v.Cost;
S>   return vehicles.First(); 
S>}
S>

S>Вот вам пример transaction script, который построен по принципу ООП. На каждый реквест, который выставлен наружу, есть отдельная "процедура". Но внутри эта процедура собирает конкретную логику из многих кусочков. Её порождает некоторый объект какого-то класса, который пользуется всеми методами ООП и паттернами проектирования — наследование, перегрузки, шаблонный метод, стратегия, фасад, you name it.
S>Ничего подобного Фаулер придумать не смог; в основном потому, что в его время об этом мало кто задумывался. Ну, и потому, что реализация некоторых аспектов такого подхода на доисторических языках требует нечеловеческих усилий.

Ничего нового. Такой подход мне знаком и я бы не сказал, что он меня как-то впечатляет. И да, он все таки больше процедурный. Вы попытались реализовать логику формирования запросов с помощью ООП. Но сама бизнес-логика и сами бизнес правила явно не выделены.
1. Признак это переменная db. Это что? Статическая переменная? Ну или контекст? — сути не меняет — привет глобальное состояние.
2. Все это больше похоже на попытку мыслить в функциональном стиле. У вас есть функции и есть данные, далее поверх этих данных вы пытаетесь навесить поведение. Но опять же делаете это не явно и у вас функции с состоянием. Тогда уж лучше разнести. Например, CheckPermissions — у вас items принимается как параметрю. А вот Permissions нет.
3. На самом деле большую опасность здесь несут неявные связи. SQL может в мгновение ока построить вам связь между сущностями. Это как спор между языками с статической типизацией и динамической. Вот вы говорите, что теперь у пользователей есть права и они мапятся по Id для всех у кого такой-то признак. И бац — оформили это в вашем запросе как джойн. В случае с мапингом на доменные сущности вам нужно заморочиться. Обьявить коллекцию, заполнить ее данными и т.п. — дофига кода. Это и плюс и минус одновременно. Если мы работаем с несложной бизнес-логикой где пару тройку доменных сущностей. Ну 10, 15. Данное свойство SQL и как следствие LINQ2DB не оказывает влияния. С другой стороны мапинг на доменные сущности дает лишь оверхэд. Но в сложных доменах обьявление класса уже является и документацией. По этому коду можно понимать модель. В SQL нужно прошерстить и держать в голове все запросы и какие они связи образуют.
4. По тому коду, что вы привели — крайне сложно отслеживать зависимости между сущностями. Вот CheckPermissions я вижу использует items и Users. Но то что он использует Permissions можно догадаться только из названия. А если я добавляю еще одну зависимость мне что метод переименовывать? Хочется верить, что нет.
5. Тесты вы как пишите? Они у вас быстрые? Или тесты для слабаков?
Re[4]: Как определить где размещать бизнес-логику
От: Nikita Lyapin Россия https://architecture-cleaning.ru/
Дата: 09.06.21 18:40
Оценка:
Здравствуйте, gandjustas, Вы писали:


NL>>Т.е. бизнес логика должна быть выражена на чистом языке программирования без примесей технических деталий.

G>Меня всегда умиляла наивность подобных утверждений.
G>Вот есть простое правило — нельзя продать два билета на одно место. Мы делаем систему для продажи билетов в театр в кассах по всему городу.

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


Верно. Но это же не значит, что остальные 99,5 приложения нужно тоже на SQL писать.
Re: Как определить где размещать бизнес-логику
От: IT Россия linq2db.com
Дата: 09.06.21 22:26
Оценка:
Здравствуйте, Nikita Lyapin, Вы писали:

NL>Часто возникают обсуждения о том где размещать бизнес-логику приложения. В итоге я собрался силами, систематизировал свои знания по этому вопрос и написал статью. Здесь


ООП само по себе уже есть добавление сложности в любую логику. Поэтому переход на ООП при усложнении бизнес-логики — это так себе решение. В некоторых случаях может помочь, но скорее всего станет только хуже.
Если нам не помогут, то мы тоже никого не пощадим.
Отредактировано 10.06.2021 1:01 IT . Предыдущая версия .
Re[5]: Как определить где размещать бизнес-логику
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.06.21 07:21
Оценка:
Здравствуйте, Nikita Lyapin, Вы писали:

NL>Ничего нового. Такой подход мне знаком и я бы не сказал, что он меня как-то впечатляет. И да, он все таки больше процедурный. Вы попытались реализовать логику формирования запросов с помощью ООП. Но сама бизнес-логика и сами бизнес правила явно не выделены.

Как это не выделена? Вполне себе выделена. В совершенно явном и понятном виде: вот есть правило про проверку разрешений, вот реализация этого правила.
Некуда делать это более ООПшным.

NL>1. Признак это переменная db. Это что? Статическая переменная? Ну или контекст? — сути не меняет — привет глобальное состояние.

В данном примере это статическая переменная. В этом нет никакой проблемы, т.к. у этой "переменной" нет состояния; но если по-вашему тут недостаточно паттернов, то можете сделать эту переменную параметром.

NL>2. Все это больше похоже на попытку мыслить в функциональном стиле. У вас есть функции и есть данные, далее поверх этих данных вы пытаетесь навесить поведение. Но опять же делаете это не явно и у вас функции с состоянием. Тогда уж лучше разнести. Например, CheckPermissions — у вас items принимается как параметрю. А вот Permissions нет.

NL>3. На самом деле большую опасность здесь несут неявные связи. SQL может в мгновение ока построить вам связь между сущностями. Это как спор между языками с статической типизацией и динамической. Вот вы говорите, что теперь у пользователей есть права и они мапятся по Id для всех у кого такой-то признак. И бац — оформили это в вашем запросе как джойн. В случае с мапингом на доменные сущности вам нужно заморочиться. Обьявить коллекцию, заполнить ее данными и т.п. — дофига кода. Это и плюс и минус одновременно.
Нет, это чистый минус.
NL>Если мы работаем с несложной бизнес-логикой где пару тройку доменных сущностей. Ну 10, 15. Данное свойство SQL и как следствие LINQ2DB не оказывает влияния.
Оказывает. Объём кода — это прямые расходы на разработку, тестирование, и поддержку. Даже если у вас доменных сущностей две. Просто вам кажется, что написать лишние 200 строк кода — это малозначимая фигня, а вот если бы их было 200 тысяч, тогда решение становится важным. На практике вы не пишете сразу 200000 строк, вы получаете их в результате тысячи доработок, в каждой из которых дописывается по 200 строк.

NL>С другой стороны мапинг на доменные сущности дает лишь оверхэд. Но в сложных доменах обьявление класса уже является и документацией.

Всё верно. Вот мы объявили Vehicle: ISecurable и сразу этим показали, что права доступа к нему контролируются через таблицу Permissions.
NL>По этому коду можно понимать модель. В SQL нужно прошерстить и держать в голове все запросы и какие они связи образуют.
И опять это зависит от того, как вы пишете этот SQL. В чистом SQL, написанном в процедурном стиле — именно так. Понять, нужно ли контролировать доступ к какой-либо сущности по таблице разрешений, можно только путём вдумчивого копания в текстах параметризованных view и хранимых процедур.
В рамках полноценного фреймворка вроде Linq вы видите эти связи прямо на уровне деклараций.

NL>4. По тому коду, что вы привели — крайне сложно отслеживать зависимости между сущностями. Вот CheckPermissions я вижу использует items и Users. Но то что он использует Permissions можно догадаться только из названия. А если я добавляю еще одну зависимость мне что метод переименовывать? Хочется верить, что нет.

Что здесь вы называете "сущностями"? То, что хранится в базе? Или те объекты, которые реализуют бизнес-логику?
В нашем примере есть некоторая реализация интерфейса IAccessPolicy (которого мы выделяем только если это вообще нужно — в простых моделях такой нужды нет, и можно просто реализовывать CheckPermissions как метод-расширение к DatabaseContext). Напимер, ACLBasedAccessPolicy. У неё будет вполне явная зависимость от IQueryable<Permission> Permissions.
У какой-то другой реализации IAccessPolicy такой зависимости может и не быть — это не свойство модели данных, а свойство бизнес-логики. Которая сегодня — одна, а завтра — совсем другая (например, заменяем ACL на RBAC).

NL>5. Тесты вы как пишите? Они у вас быстрые? Или тесты для слабаков? \

А что именно вы хотите тестировать? Видите ли, когда вы врукопашную велосипедите стандартный набор репозиториев и прочего хлама, вам придётся тестировать код репозиториев и прочего хлама.
Когда вы пишете код в указанном стиле, вам не нужно тестировать linq2db — его тестируют другие люди. Вам нужно только протестировать, что результатом конкретной реализации IAccessPolicy.CheckPermissions является наложение требуемого предиката.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: Как определить где размещать бизнес-логику
От: Nikita Lyapin Россия https://architecture-cleaning.ru/
Дата: 10.06.21 07:58
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

S>Когда вы пишете код в указанном стиле, вам не нужно тестировать linq2db — его тестируют другие люди. Вам нужно только протестировать, что результатом конкретной реализации IAccessPolicy.CheckPermissions является наложение требуемого предиката.
Странный вопрос. Даже очень. Тестировать я хочу бизнес-правила. Например, что при задании определенных пермишенов мне только заданные items отоброжаются. И да, Linq2Db мне тестировать ну совсем не хочется. И как это реализовать в вашем примере без теста Linq2Db? С статическими то переменными в коде... выкрутиться можно. Но будет такое себе зрелище. Просто интересно как вы это решаете.
Re[7]: Как определить где размещать бизнес-логику
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.06.21 08:25
Оценка:
Здравствуйте, Nikita Lyapin, Вы писали:
NL>Странный вопрос. Даже очень. Тестировать я хочу бизнес-правила. Например, что при задании определенных пермишенов мне только заданные items отоброжаются.
Ничего странного. Вопрос "а что именно тестируется" очень важен. К примеру, я не думаю, что вы в вашем коде проверяете, что компилятор, стандартная библиотека, и процессор корректно выполняют, скажем, умножение.
Если мы говорим о юнит-тестах, то они тестируют именно конкретный юнит.
Когда вы тестируете SQL, вряд ли вы тестируете, что в результат join ... on ... попадают только те строчки, которые попадают под предикат. Эту работу уже выполнила команда QA-инженеров соответствующей СУБД.

Так и тут — у вас есть некоторые обязанности кода, их вы и проверяете.

NL>И да, Linq2Db мне тестировать ну совсем не хочется. И как это реализовать в вашем примере без теста Linq2Db? С статическими то переменными в коде... выкрутиться можно. Но будет такое себе зрелище. Просто интересно как вы это решаете.


Очевидным способом — проверяем, что при передаче обычного пользователя возвращается результат Join, а при передаче суперпользователя — тот же экземпляр IQueryable.
Можно проверить текст результирующего SQL, но это контрпродуктивно в случае поддержки разных SQL-диалектов.

Интеграционные тесты, как и везде, будут относительно медленными, и ничем не будут отличаться от интеграционных тестов любого Enterprise-приложения.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: Как определить где размещать бизнес-логику
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.06.21 09:08
Оценка:
Здравствуйте, Nikita Lyapin, Вы писали:

NL>Здравствуйте, gandjustas, Вы писали:



NL>>>Т.е. бизнес логика должна быть выражена на чистом языке программирования без примесей технических деталий.

G>>Меня всегда умиляла наивность подобных утверждений.
G>>Вот есть простое правило — нельзя продать два билета на одно место. Мы делаем систему для продажи билетов в театр в кассах по всему городу.

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


NL>Верно. Но это же не значит, что остальные 99,5 приложения нужно тоже на SQL писать.


Если мы повторим упражнение для других "бизнес-правил", то внезапно окажется что 99,5% из них проще выразить в SQL, чем в C#.
Например для той же системы продажи билетов: нельзя продать билет на место, если соседнее было куплено (антиковидное ограничение).
В SQL это элементарно: в выборку свободных мест доставляется условие, филтрующее места с номерами +\-1 от купленного. А в "доменной модели" как будет?
Re[7]: Как определить где размещать бизнес-логику
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.06.21 09:11
Оценка:
Здравствуйте, Nikita Lyapin, Вы писали:

NL>Странный вопрос. Даже очень. Тестировать я хочу бизнес-правила. Например, что при задании определенных пермишенов мне только заданные items отоброжаются. И да, Linq2Db мне тестировать ну совсем не хочется. И как это реализовать в вашем примере без теста Linq2Db? С статическими то переменными в коде... выкрутиться можно. Но будет такое себе зрелище. Просто интересно как вы это решаете.


Я не знаю как там у linq2db, но у EF вполне можно инмемори контекст для тестов сделать. И в конце концов что мешает тесты запускать на базе sqlite например?
Re[8]: Как определить где размещать бизнес-логику
От: Nikita Lyapin Россия https://architecture-cleaning.ru/
Дата: 10.06.21 09:23
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, Nikita Lyapin, Вы писали:


NL>>Странный вопрос. Даже очень. Тестировать я хочу бизнес-правила. Например, что при задании определенных пермишенов мне только заданные items отоброжаются. И да, Linq2Db мне тестировать ну совсем не хочется. И как это реализовать в вашем примере без теста Linq2Db? С статическими то переменными в коде... выкрутиться можно. Но будет такое себе зрелище. Просто интересно как вы это решаете.


G>Я не знаю как там у linq2db, но у EF вполне можно инмемори контекст для тестов сделать. И в конце концов что мешает тесты запускать на базе sqlite например?


Решение с sqllite — костыль. Давайте себе честно в этом признаемся. Разница с постгресом будет где-то в два раза быстрее. Настоящие true unit тесты будут в тысячи раз быстрее. Тут я оперирую конкретным
опытом рефакторинга одного проекта, где мне довелось через все этим стадии пройти.
Ну вот вы пишите с EF — да уже лучше. Немно сдвинули нашу кривую затратности (см график из статьи). Но опять же не всегда имеет смысл. Для простейшего проекта где две таблицы и все — достаточно дапера. Дазем все уложнять. И интеграционные тесты там вполне могут жить, потому что их не много и написать их легко.
Re[9]: Как определить где размещать бизнес-логику
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.06.21 11:08
Оценка:
Здравствуйте, Nikita Lyapin, Вы писали:

NL>1. Тестов либо нет, либо они делаются QA ручками без всяких CI CD. Либо они интеграционные и медленные. И доля интеграционных тестов — большинство. Все это работает и так делать можно. Но если проект у вас не крупный. И даже не средний. Если тесты выполняются руками, то в крупном проекте регрес будет проходить за неделю. Правите в одном месте — опять полный регрес. Если интеграционные тесты — в крупном проекте их тысячи. Должны быть быстрыми для комфортной разработки.

NL>2. Обьем кода от ООП (ОРМ и обвесов) не растет линейно. Т.е. да, вы в начале добавляете 200 строк кода. Но по мере роста вы не добавляете по 200 строк на каждое бизнес-правило. Наоборот. Дополнительный оверхед достигается за счет мапинга, сервисов и репозиториев. Далее вы уже используете готовую инфраструктуру. Отсюда вывод — для маленького проекта не имеет смысла. Дла большого — имеет.
NL>3. Все такпи статичекие переменные — это как раз признак процедурности. Ну или в любом случае затрудненной сопровождаемости кода. Командная работа, поять же сложный и комплексный домен, который невозомжно уместить в голове — все это сразу мимо. И опять — для маленького проекта все окей.
NL>Итого, стиль который вы описали отлично подходит для небольшого по обьему проекта. Со сложным — будут проблемы. Единственное, что тут нужно учесть — это микросервисы. С их приходом каждый конкретный микросервис в целом простой. И там вполне можно так писать. И я бы даже сказал, что иногда нужно так и только так.
NL>Вот такая у меня позиция.
Давайте так — покажите код, который реализует вот это простое бизнес-правило "сотруднику предоставляется самый дешёвый автомобиль среди тех, которые ему можно использовать".
С тестами.
Может быть, действительно, linq будет плохим ответом на подобную задачу.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[11]: Как определить где размещать бизнес-логику
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.06.21 12:54
Оценка:
Здравствуйте, Nikita Lyapin, Вы писали:

NL>Я могу вам порекомендовать курс

Открою тайну, аппелция к "авторитетам" тут не работает. Даже если бы по ссылке был курс фаулера это нисколько бы не укепило веру в то, что он говорит не туфту.


NL>Там все подробно разбирается. Если у меня будет время — напишу вам пример, который вы хотите. Но чуть позже. Пока времени нет.

Как найдете время напишите пример веб-приложения, где будет использоваться EF или linq2db, и в котором "domain model" выигрывает по метрикам у "transaction script".
Метрики которые студия собирать умеет — LOC, class coupling, code complexity, depth of inheritance

Я, к сожалению, за все 15 лет холиваров не увидел ни одного такого примера.
Re[12]: Как определить где размещать бизнес-логику
От: Nikita Lyapin Россия https://architecture-cleaning.ru/
Дата: 10.06.21 12:57
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Здравствуйте, Nikita Lyapin, Вы писали:


NL>>Я могу вам порекомендовать курс

G>Открою тайну, аппелция к "авторитетам" тут не работает. Даже если бы по ссылке был курс фаулера это нисколько бы не укепило веру в то, что он говорит не туфту.
Причем тут авторитеты? Вы хотите пример учебный — вот вам. Его ведь тоже разрабатывать нужно, писать. Так чтобы все было понятно. Поэтому люди за это небольшую плату берут. Я думаю, что уж можно раскошелится на курс выше если интересно. Если не интересно — не надо.

NL>>Там все подробно разбирается. Если у меня будет время — напишу вам пример, который вы хотите. Но чуть позже. Пока времени нет.

G>Как найдете время напишите пример веб-приложения, где будет использоваться EF или linq2db, и в котором "domain model" выигрывает по метрикам у "transaction script".
G>Метрики которые студия собирать умеет — LOC, class coupling, code complexity, depth of inheritance

G>Я, к сожалению, за все 15 лет холиваров не увидел ни одного такого примера.

К сожалению для кого?
Будет время — напишу, так уж и быть.
Меня сейчас больше интересуют фикусы. И как они могут задушить...
Отредактировано 10.06.2021 13:03 Nikita Lyapin . Предыдущая версия .
Re[8]: Как определить где размещать бизнес-логику
От: IT Россия linq2db.com
Дата: 10.06.21 13:26
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Я не знаю как там у linq2db, но у EF вполне можно инмемори контекст для тестов сделать. И в конце концов что мешает тесты запускать на базе sqlite например?


Если не баловаться диалектами SQL и специфическими фичами конкретных СУБД, то ничего.
Если нам не помогут, то мы тоже никого не пощадим.
Re[13]: Как определить где размещать бизнес-логику
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.06.21 13:34
Оценка:
Здравствуйте, Nikita Lyapin, Вы писали:

NL>Здравствуйте, gandjustas, Вы писали:


G>>Здравствуйте, Nikita Lyapin, Вы писали:


NL>>>Я могу вам порекомендовать курс

G>>Открою тайну, аппелция к "авторитетам" тут не работает. Даже если бы по ссылке был курс фаулера это нисколько бы не укепило веру в то, что он говорит не туфту.
NL>Причем тут авторитеты? Вы хотите пример учебный — вот вам. Его ведь тоже разрабатывать нужно, писать. Так чтобы все было понятно. Поэтому люди за это небольшую плату берут. Я думаю, что уж можно раскошелится на курс выше если интересно. Если не интересно — не надо.
Смотри: был конкретный вопрос, сценарий. Ты вместо ответа на него кинл сылку на курс, где не только нет ответа на этот вопрос, но и нет сравнения с другии подходами для решения тех же задач.
Тут два варианта: или ты так слился с обсуждения, или решил авторитетом автора курса надавить на собеседника.
Re[12]: Как определить где размещать бизнес-логику
От: IT Россия linq2db.com
Дата: 10.06.21 13:41
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Самое интересное, что видел (но так и не изучил глубоко) — это использование для бизнес-логики ФП на F#. Там при помощи алгебраических типов данных довольно круто описываются ограничения доменной модели.


АТД и ПМ штука мощная, но хорошо работает для консервативных моделей с предсказуемой логикой. А у большей часть типовой бизнес логики всё плохо с формализацией и ещё хуже с предсказуемостью. Хотя нет, предсказание о том, что всё будет только хуже обычно сбывается.
Если нам не помогут, то мы тоже никого не пощадим.
Re[14]: Как определить где размещать бизнес-логику
От: Nikita Lyapin Россия https://architecture-cleaning.ru/
Дата: 10.06.21 14:09
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Смотри: был конкретный вопрос, сценарий. Ты вместо ответа на него кинл сылку на курс, где не только нет ответа на этот вопрос, но и нет сравнения с другии подходами для решения тех же задач.

G>Тут два варианта: или ты так слился с обсуждения, или решил авторитетом автора курса надавить на собеседника.

Стас, надовить авторитетом на собеседника? Ну ладно... каких-то 5 лет назад Тот же автор курса, тот же Стас и ровно такие же вопросы. Вот человек сделал пример. Ну так почему бы его не посмотреть за эти 5 лет? Так-то и не 15 лет можно потратить, а все 30 лет на холивары. Без результатов.

Еще раз. Не вижу никакой необходимости тратить время на создание примера по общеизвестной и хорошо изученной проблеме. Если у меня спрашивают пример с уровнями изоляции транзакций — я просто кидаю ссылку на книжку или статью, где это хорошо описано. Так в данно случае и поступил.
В противном случае мы получим такой троллинг. Когда в диалоге один не понимает якобы и тратит время своего собеседника на выдуманные примеры. Не очеь мне это интересно.
Re[15]: Как определить где размещать бизнес-логику
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 10.06.21 14:34
Оценка:
Здравствуйте, Nikita Lyapin, Вы писали:

NL>Здравствуйте, gandjustas, Вы писали:


G>>Смотри: был конкретный вопрос, сценарий. Ты вместо ответа на него кинл сылку на курс, где не только нет ответа на этот вопрос, но и нет сравнения с другии подходами для решения тех же задач.

G>>Тут два варианта: или ты так слился с обсуждения, или решил авторитетом автора курса надавить на собеседника.

NL>Стас, надовить авторитетом на собеседника? Ну ладно... каких-то 5 лет назад Тот же автор курса, тот же Стас и ровно такие же вопросы. Вот человек сделал пример. Ну так почему бы его не посмотреть за эти 5 лет? Так-то и не 15 лет можно потратить, а все 30 лет на холивары. Без результатов.

Там нет примеров, которые хоть что-то показывают. Не описаны задачи, проблемы и их решения.


NL>Еще раз. Не вижу никакой необходимости тратить время на создание примера по общеизвестной и хорошо изученной проблеме.

Наверное поэтому 15 лет холивары не утихают, раз проблема такая изученная.

NL>Если у меня спрашивают пример с уровнями изоляции транзакций — я просто кидаю ссылку на книжку или статью, где это хорошо описано. Так в данно случае и поступил.

Уровни изоляции достаточно формально описаны в стандарте, которому следуют многие создатели движков СУБД. А "domain model" вообще не имеет формального описания, более того многие даже буксуют на том, чтобы формально очертить границы DDD.
Поэтому ссылки на курсы и статьи по теме без сравнения разных подходов и хотя бы попоыток формализации — не более ем аппеляция к авторитетам, которые в общем-то не очень авторитеты.
Re[16]: Как определить где размещать бизнес-логику
От: Nikita Lyapin Россия https://architecture-cleaning.ru/
Дата: 10.06.21 14:41
Оценка:
Здравствуйте, gandjustas, Вы писали:

NL>>Стас, надовить авторитетом на собеседника? Ну ладно... каких-то 5 лет назад Тот же автор курса, тот же Стас и ровно такие же вопросы. Вот человек сделал пример. Ну так почему бы его не посмотреть за эти 5 лет? Так-то и не 15 лет можно потратить, а все 30 лет на холивары. Без результатов.

G>Там нет примеров, которые хоть что-то показывают. Не описаны задачи, проблемы и их решения.
В курсе есть примеры. И репозиторий тоже есть.

NL>>Если у меня спрашивают пример с уровнями изоляции транзакций — я просто кидаю ссылку на книжку или статью, где это хорошо описано. Так в данно случае и поступил.

G>Уровни изоляции достаточно формально описаны в стандарте, которому следуют многие создатели движков СУБД. А "domain model" вообще не имеет формального описания, более того многие даже буксуют на том, чтобы формально очертить границы DDD.
G>Поэтому ссылки на курсы и статьи по теме без сравнения разных подходов и хотя бы попоыток формализации — не более ем аппеляция к авторитетам, которые в общем-то не очень авторитеты.
В DDD точно так же формально все описано. Есть бизнесовые сервисы, есть application сервисы, есть репозитории, есть абстрактные фабрики, есть агрегаты. И когда я вижу в примере у человека процессор, как в ветке ниже — то скорее всего он всего этого не знает. И ему не мешало бы освежить знания. Не так?
Re[17]: Как определить где размещать бизнес-логику
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 11.06.21 08:10
Оценка:
Здравствуйте, Nikita Lyapin, Вы писали:

NL>>>Если у меня спрашивают пример с уровнями изоляции транзакций — я просто кидаю ссылку на книжку или статью, где это хорошо описано. Так в данно случае и поступил.

G>>Уровни изоляции достаточно формально описаны в стандарте, которому следуют многие создатели движков СУБД. А "domain model" вообще не имеет формального описания, более того многие даже буксуют на том, чтобы формально очертить границы DDD.
G>>Поэтому ссылки на курсы и статьи по теме без сравнения разных подходов и хотя бы попоыток формализации — не более ем аппеляция к авторитетам, которые в общем-то не очень авторитеты.
NL>В DDD точно так же формально все описано.
Увы, нет. "Формально" это когда два человека могут прочитать описание и сделать одинаково работающий код.

NL>Есть бизнесовые сервисы, есть application сервисы, есть репозитории, есть абстрактные фабрики, есть агрегаты.

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

Резонно возникает вопрос: а что такое вообще DDD? Может это просто набор паттернов? Тогда расматривать DDD в отрыве от задачи нет смысла. И как понять где начинается и кончается DDD? Если я использую application service это DDD?

В книжке эванса делется упор на то, что DDD это методика анализа в первую очередь, ubiquitous language и все такое. Правда даже в книге эванса переход от анализа к проектированию описан мутно. Нам предлагается самостоятельно понять как нам предметную область поделить на агрегаты и сервисы.

А может DDD это фреймворк, где в некоторую готовую структуру надо написатьсвою логику? Но я такой структуры не видел.
Re[18]: Как определить где размещать бизнес-логику
От: Nikita Lyapin Россия https://architecture-cleaning.ru/
Дата: 11.06.21 08:55
Оценка:
Здравствуйте, gandjustas, Вы писали:

NL>>Есть бизнесовые сервисы, есть application сервисы, есть репозитории, есть абстрактные фабрики, есть агрегаты.

G>Это все не нужно для того, чтобы сделать приложение. У меня больше одного работающего приложения, в которых нет репозитоиев, абстрактных фабрик и агрегатов.

Какова команда, которая его сопровождает? Как они между собой взаимодействуют? Это ведь не один человек писал и поддерживал все. Верно?
Мы ведь говорим про крупные проекты. Для небольших как я и писал выше все будет работать как вы описали.
Re[19]: Как определить где размещать бизнес-логику
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 11.06.21 10:25
Оценка:
Здравствуйте, Nikita Lyapin, Вы писали:

NL>Здравствуйте, gandjustas, Вы писали:


NL>>>Есть бизнесовые сервисы, есть application сервисы, есть репозитории, есть абстрактные фабрики, есть агрегаты.

G>>Это все не нужно для того, чтобы сделать приложение. У меня больше одного работающего приложения, в которых нет репозитоиев, абстрактных фабрик и агрегатов.

NL>Какова команда, которая его сопровождает? Как они между собой взаимодействуют? Это ведь не один человек писал и поддерживал все. Верно?

NL>Мы ведь говорим про крупные проекты. Для небольших как я и писал выше все будет работать как вы описали.

Это много разных проектов, по нексколько человек сопровождают. А в чем могут быть проблемы?
Re[12]: видео vs текст
От: Sharov Россия  
Дата: 11.06.21 17:27
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Смотреть видео — самый бездарный способ потратить время разработчика. Я читаю текст примерно в 5-10 раз быстрее, чем закадровый голос в этом курсе.


У меня ровно обратный опыт, если есть скорость 2х. А 2х читать я не умею. При прочих равных предпочту видео.
Кодом людям нужно помогать!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.