такая постановка вопроса не совсем корректна, если подразумевается управление авторизации доступа к ресурсам. это задача каждого микросервиса т.к. является частью домена. само определение роли пользователя может изменятся в контексте сервиса. на общем уровне могу представить себе управление распределением ролей в контексте тех или иных микросервисов.
IMHO Смешивать Security с Domain как-то попахивает. Тем более в таком порядке. 1. Symfony не интересует ваш Domain. 2. По определению у каждого микросервиса есть своя база данных. Т.е. только у одного есть (может/должна быть) информация о юзерах 3. Понятие роли определяется в контексте определенного микросервиса
В общем, если вы первым шагом запрашиваете Domain/User, то вы нарушаете Single Responsibility
Хотели протестировать один репозиторий, в итоге заменили один репозиторий на другой репозиторий, и протестировали второй.
Такой подход не для тестирования самого репозитория, а для тестирования пользователей репозитория. То есть, если вам на пример надо протестировать фильтрацию данных (как в примере автора), то такой подход, соглашусь, не поможет.
Ошибка автора в выборе примера. Но с аргументацией автора против использования моков согласен.
Да, тема не из самых простых :) Если посмотреть статью википедии на английском, то там упоминается интервью с бабой Варей. Видео есть на ютьюбе. В нем она называет этот принцип behavioral subtyping
Самый простой способ на пальцах объяснить принцип: Есть класс List. Есть два наследника FirstInFirstOutList и LastInFirstOutList Следуя принципу, наследники по отношению к пользователю не взаимозаменяемы, потому что их поведение разное.
Хотел добавить, что "сложность" LSP не столько в контрактах, сколько в поведении. Если интересно, посмотрите про Behavioral subtyping.
По-быстрому: У вас две реализации Linked List. FIFO vs LIFO. Контракты (Interface) идентичны. Но в данном случае нельзя заменить один класс другим не нарушив LSP.
как я понимаю и преподношу CQRS это в первую очередь "смысловое" разделение бизнеса, его логики и соответственно исполнения. все основывается на том, что относительно "одни и те же данные" в разных контекстах, оказывается, совсем не обязательно "совместимы".
например, в разных контекстах условного онлайн-магазина данные пользователя магазином могут быть совершенно разными. для формирования заказа нужен адрес доставки, а для бухгалтерии эта информация совершенно неинтересна.
повышенная эффективность запросов данных это только второстепенный аспект. в первую очередь достигается чистота и порядок в данных нужных для реализации бизнеса в определенном контексте.
по отношению к REST данный паттерн также имеет преимущество в том, что он более соответствует реальности. так как коммуникация осуществляется путем конкретно определенных команд и запросов. каждая команда или запрос соответсвует определенному бизнес-кейсу. а вот REST относительно далек от бизнеса пытаясь "переписать" процессы с помощью жестко ограниченного набора глаголов.
ради забавы. попробуйте "понятно" описать в REST такой процесс как "расторжение договора" со всеми (ну, хотя бы несколько) истекающими из этого последствиями
+1
Тоже сразу о Лоренце подумал. Тем более, что тот довольно "успешно" экстраполировал свои результаты для подтверждения отнюдь не однозначных теорий популярных в 30-е годы.
В общем, если уж выбирать пример селекционного отбора, то однозначно есть примеры интереснее, чем доместицирование лис )
в том то и печаль, что ничего я не натягиваю.
Никто не спорит, что ИТ-фразы становятся нормальными. И было бы вообще супер, если бизнес по-настоящему понимал, что они означают. Но вот только это совсем еще не так. Да и если разобраться надобности тут тоже особой нет. Скорее даже наоборот.
Но ваш аргумент насчёт "вредит" интересен. Вы серьезно не видите, что "сайт" ничто иное как лишь еще один из каналов сбыта товара? А сам товар все еще уходит со склада или прилавков? Или вы в духе 60-х товары по телевизору "получать" хотите?
Попробуйте по-настоящему проанализировать бизнес-процесс.
В общем, перестаньте бизнесу объяснять, как он должен работать. Лучше научитесь задавать вопросы и слушать.
ну, во первых я сказал "в подавляющем большинстве". конечно, можно найти пример, где "сохранить" как термин из бизнеса вполне таким и является.
но ваш пример очень хороший пример, когда либо бизнес начинает заниматься программированием, либо программисты начинают объяснять как устроен бизнес. (вместо того, чтобы правильно задавать правильные вопросы).
попробуйте написать объяснение вами запрашиваемого функционала с точки зрения владельца сайта. то есть продавца. но при этом не используя ит-лексику. то есть "сохранить содержимое корзины, когда клиент покидает магазин"
я начну:
потенциальный покупатель заходит в наш магазин. он берет корзинку и ходит с ней по магазину. товары, которые ему приглянулись, он складывает в корзинку.
…
а теперь вы. но не забывайте, пожалуйста, и о таких нюансах, как:
скоропортящиеся продукты
популярные или дорогие продукты, которые хотелось бы все таки продать
не совсем понимаю, как вы хотите с ним спорить? в принципе он просто сожалеет о том, что в свое время выразился недостаточно ясно и был поэтому непонят.
а вот как раз массовая трактовка и привела к спорам вокруг самого принципа и его значения, потому что объем "ответственности" сложно установить и просто оспорить, основываясь на принципы инкапсюляции на уровне кода.
вы, похоже, не стали смотреть, кого я цитировал. это поправки и разъяснение к пониманию принципа от самого "изобретателя". так что тут ничего "спорного" быть, по-моему, не может.
если вы не разрабатываете очередной phpMyAdmin, то (повторюсь), с точки зрения бизнеса в подавляющем большинстве случаев нет логики "сохранить какие-либо данные". само слово "сохранить" неуместно.
конечно, вы можете ОРМ класс сделать одновременно и репозиторием для бизнеса. но тогда вы нарушаете single responsibility.
но ваш аргумент с интерфейсом поддержу:
согласен, этот интерфейс (DataRepository) определяет функционал необходимой бизнесу. но могу вас уверить, что у вас возникнут проблемы, как только вы захотите имплементировать поиск по данным.
паттерн репозитория предусматривает для поиска данных использование паттерна specification
Client objects construct query specifications declaratively and submit them to Repository for satisfaction
но для разных типов конкретного "хранилища" (бд, файл, in-memory) Specification или нужно пилить самому или это уже сделали, но заточенный под конкретную технологию (например Criteria by Doctrine). все это уместить в один толковый (строго типизированный) интерфейс будет сложно.
ну и опять таки оригинал
A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection
This principle is about people.
When you write a software module, you want to make sure that when changes are requested, those changes can only originate from a single person, or rather, a single tightly coupled group of people representing a single narrowly defined business function.
с последним согласен. хотя, имхо, чтобы позволить себе нарушать такие рекомендации, нужно быть достаточно уверенным в том, что делаешь. то есть уметь абсолютно объяснить отклонение от "правил" (нет, это не законы)
ОРМ не является чем-то "для доступа к данным" с точки зрения бизнеса. в большинстве случаев ОРМ для бизнеса не предоставляет никакого интереса. какая разница для владельца какого-либо шопа где хранятся его данные? скорее всего он даже не знает о том, что кроме ОРМ есть к примеру ОДМ. но вот "список товаров в наличии" ему совсем не безразличен. в любом случае для владельца шопа бизнес это "купи где-то товар, чтобы он был в наличии в магазине, продай этот товар изъяв его из наличия в магазине". и нет, владельцу магазина глубоко безразлично, как устроен "склад с товарами"
репозиторий это и есть тот самый "прилавок" или "склад" с точки зрения продавца или покупателя.
ну, зачем так? я сам в основном на ПХП. это все не столь от языка зависит, сколько от подхода к разработке.
но согласен, на ПХП проще наделать непотребного.
все верно. координация и управление микросервисами и есть один из главных минусов такой архитектуры
такая постановка вопроса не совсем корректна, если подразумевается управление авторизации доступа к ресурсам. это задача каждого микросервиса т.к. является частью домена. само определение роли пользователя может изменятся в контексте сервиса.
на общем уровне могу представить себе управление распределением ролей в контексте тех или иных микросервисов.
IMHO
Смешивать Security с Domain как-то попахивает. Тем более в таком порядке.
1. Symfony не интересует ваш Domain.
2. По определению у каждого микросервиса есть своя база данных. Т.е. только у одного есть (может/должна быть) информация о юзерах
3. Понятие роли определяется в контексте определенного микросервиса
В общем, если вы первым шагом запрашиваете Domain/User, то вы нарушаете Single Responsibility
спасибо. давно так не смеялся.
а оно вам принципиально обязательно? есть такое понятие как "констатирование факта". т.е без оценки в рамках "нытья" или "радости".
Такой подход не для тестирования самого репозитория, а для тестирования пользователей репозитория. То есть, если вам на пример надо протестировать фильтрацию данных (как в примере автора), то такой подход, соглашусь, не поможет.
Ошибка автора в выборе примера. Но с аргументацией автора против использования моков согласен.
Да, тема не из самых простых :)
Если посмотреть статью википедии на английском, то там упоминается интервью с бабой Варей. Видео есть на ютьюбе. В нем она называет этот принцип behavioral subtyping
Самый простой способ на пальцах объяснить принцип:
Есть класс List. Есть два наследника FirstInFirstOutList и LastInFirstOutList
Следуя принципу, наследники по отношению к пользователю не взаимозаменяемы, потому что их поведение разное.
как то так
Хотел добавить, что "сложность" LSP не столько в контрактах, сколько в поведении. Если интересно, посмотрите про Behavioral subtyping.
По-быстрому:
У вас две реализации
Linked List
. FIFO vs LIFO. Контракты (Interface) идентичны. Но в данном случае нельзя заменить один класс другим не нарушив LSP.https://www.youtube.com/watch?v=-Z-17h3jG0A
все ниже сказанное сугубо имхо
как я понимаю и преподношу CQRS это в первую очередь "смысловое" разделение бизнеса, его логики и соответственно исполнения. все основывается на том, что относительно "одни и те же данные" в разных контекстах, оказывается, совсем не обязательно "совместимы".
например, в разных контекстах условного онлайн-магазина данные пользователя магазином могут быть совершенно разными. для формирования заказа нужен адрес доставки, а для бухгалтерии эта информация совершенно неинтересна.
повышенная эффективность запросов данных это только второстепенный аспект. в первую очередь достигается чистота и порядок в данных нужных для реализации бизнеса в определенном контексте.
по отношению к REST данный паттерн также имеет преимущество в том, что он более соответствует реальности. так как коммуникация осуществляется путем конкретно определенных команд и запросов. каждая команда или запрос соответсвует определенному бизнес-кейсу. а вот REST относительно далек от бизнеса пытаясь "переписать" процессы с помощью жестко ограниченного набора глаголов.
ради забавы. попробуйте "понятно" описать в REST такой процесс как "расторжение договора" со всеми (ну, хотя бы несколько) истекающими из этого последствиями
тот кто вызывает, должен знать, что он хочет.
если вы аргументируете тем, что последний, в данном случае, параметр может быть неизвестен вызывающему, то флаг вам в руки и удачи )
однозначо :)
+1
Тоже сразу о Лоренце подумал. Тем более, что тот довольно "успешно" экстраполировал свои результаты для подтверждения отнюдь не однозначных теорий популярных в 30-е годы.
В общем, если уж выбирать пример селекционного отбора, то однозначно есть примеры интереснее, чем доместицирование лис )
в том то и печаль, что ничего я не натягиваю.
Никто не спорит, что ИТ-фразы становятся нормальными. И было бы вообще супер, если бизнес по-настоящему понимал, что они означают. Но вот только это совсем еще не так. Да и если разобраться надобности тут тоже особой нет. Скорее даже наоборот.
Но ваш аргумент насчёт "вредит" интересен. Вы серьезно не видите, что "сайт" ничто иное как лишь еще один из каналов сбыта товара? А сам товар все еще уходит со склада или прилавков? Или вы в духе 60-х товары по телевизору "получать" хотите?
Попробуйте по-настоящему проанализировать бизнес-процесс.
В общем, перестаньте бизнесу объяснять, как он должен работать. Лучше научитесь задавать вопросы и слушать.
ну, во первых я сказал "в подавляющем большинстве". конечно, можно найти пример, где "сохранить" как термин из бизнеса вполне таким и является.
но ваш пример очень хороший пример, когда либо бизнес начинает заниматься программированием, либо программисты начинают объяснять как устроен бизнес. (вместо того, чтобы правильно задавать правильные вопросы).
попробуйте написать объяснение вами запрашиваемого функционала с точки зрения владельца сайта. то есть продавца. но при этом не используя ит-лексику. то есть "сохранить содержимое корзины, когда клиент покидает магазин"
я начну:
потенциальный покупатель заходит в наш магазин. он берет корзинку и ходит с ней по магазину. товары, которые ему приглянулись, он складывает в корзинку.
…
а теперь вы. но не забывайте, пожалуйста, и о таких нюансах, как:
не совсем понимаю, как вы хотите с ним спорить? в принципе он просто сожалеет о том, что в свое время выразился недостаточно ясно и был поэтому непонят.
а вот как раз массовая трактовка и привела к спорам вокруг самого принципа и его значения, потому что объем "ответственности" сложно установить и просто оспорить, основываясь на принципы инкапсюляции на уровне кода.
вы, похоже, не стали смотреть, кого я цитировал. это поправки и разъяснение к пониманию принципа от самого "изобретателя". так что тут ничего "спорного" быть, по-моему, не может.
если вы не разрабатываете очередной phpMyAdmin, то (повторюсь), с точки зрения бизнеса в подавляющем большинстве случаев нет логики "сохранить какие-либо данные". само слово "сохранить" неуместно.
конечно, вы можете ОРМ класс сделать одновременно и репозиторием для бизнеса. но тогда вы нарушаете single responsibility.
но ваш аргумент с интерфейсом поддержу:
согласен, этот интерфейс (DataRepository) определяет функционал необходимой бизнесу. но могу вас уверить, что у вас возникнут проблемы, как только вы захотите имплементировать поиск по данным.
паттерн репозитория предусматривает для поиска данных использование паттерна specification
но для разных типов конкретного "хранилища" (бд, файл, in-memory) Specification или нужно пилить самому или это уже сделали, но заточенный под конкретную технологию (например Criteria by Doctrine). все это уместить в один толковый (строго типизированный) интерфейс будет сложно.
ну и опять таки оригинал
то есть репозиторий это нечто между двумя слоями.
single responsibility это не про "одна причина для изменения".
это про "кто отвечает за данный кусок системы"
https://blog.cleancoder.com/uncle-bob/2014/05/08/SingleReponsibilityPrinciple.html
с последним согласен. хотя, имхо, чтобы позволить себе нарушать такие рекомендации, нужно быть достаточно уверенным в том, что делаешь. то есть уметь абсолютно объяснить отклонение от "правил" (нет, это не законы)
ОРМ не является чем-то "для доступа к данным" с точки зрения бизнеса. в большинстве случаев ОРМ для бизнеса не предоставляет никакого интереса. какая разница для владельца какого-либо шопа где хранятся его данные? скорее всего он даже не знает о том, что кроме ОРМ есть к примеру ОДМ. но вот "список товаров в наличии" ему совсем не безразличен. в любом случае для владельца шопа бизнес это "купи где-то товар, чтобы он был в наличии в магазине, продай этот товар изъяв его из наличия в магазине". и нет, владельцу магазина глубоко безразлично, как устроен "склад с товарами"
репозиторий это и есть тот самый "прилавок" или "склад" с точки зрения продавца или покупателя.
этого должно быть уже более чем достаточно, чтобы задуматься, а почему вдруг используются разные слова.
никто ничего не путает. просто два способа решить одну и ту же проблему.
ваша аргументация наталкивает на мысль, что у вас понимание "relation" в ORM и соответственно ralational database иное.
single responsibility
ну, зачем так? я сам в основном на ПХП. это все не столь от языка зависит, сколько от подхода к разработке.
но согласен, на ПХП проще наделать непотребного.