@oop_ru

Страница 778 из 785
Дмитрий
14.10.2018
12:34:53
Пытаться применить нет, но сообщить о его просрочке можно

Sergey
14.10.2018
12:35:08
так что можно опять же сначала проверить все прекондишены а уже потом сраждаться с инвариантами. И получить список ошибок для прекондишенов (это просто) а с инвариантами просто фэйлить по одной ошибке. Поскольку у тебя применение промокода все же зависит от брони

Google
Дмитрий
14.10.2018
12:35:50
Я это и предложил, вынести проверки прекондишенов в отдельный метод

Sergey
14.10.2018
12:36:12
еще раз - прекондишены и инварианты - разные вещи

ой все короч

Дмитрий
14.10.2018
12:36:37
))

Ты почти понял меня)

Sergey
14.10.2018
12:37:09
прикол инвариантов в том что у тебя врядли в одной бизнес операции будут независимые инварианты. Как следствие - говорить о получении "списка" нарушений инвариантов глупо

инварианты - они как бы инварианты системы

и изначально дискуссия была только про инварианты, в следствии чего я начал подозревать что человек смешивает понятие прекондишенов и инвариантов

Дмитрий
14.10.2018
12:40:27
Ты согласен с тем что для атомарного перехода от одного состояния к другому с соблюдением всех инвариантов может потребоваться проверка 2 и более независимых условий?

Sergey
14.10.2018
12:41:59
независимых - нет. Потому что переход от одной проверки к другой требует изменения состояния.

Дмитрий
14.10.2018
12:42:06
Например человек может сделать шаг и изменить состояние, только если у него будет обе ноги

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

Sergey
14.10.2018
12:46:59
еще раз... 1. конфликт в промокодах (один промокод остался) и нет конфликта по местам - если проверки "независимы" то фэйл с промокодами не должен влиять на бронь. 2. конфликт с местами, промокодов всем хватает - бронь не будет произведена 3. конфликт и с местами и с промокодом - ты не сможешь забронировать а стало быть не сможешь применить промокод. Как следствие зафэйлится всегда только одна операция (нету конфликта). Что делает эти проверки зависимыми

Google
Дмитрий
14.10.2018
12:55:37
Проверки зависимы если возможность выполнить одну проверку появляется после совершения другой проверки. Например, 1. Ввел ли пользователь купон, 2. Существует ли купон. 3. Просрочен ли купон. В нашем случае чтобы проверить купон, не обязательно бронить место, значит результат проверки можно показать сразу независимо от того, свободно ли место

Sergey
14.10.2018
12:59:13
все это - прекондишены а не инварианты.

их можно проверять отдельно

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

а это были последние места которые я считаю удобными для себя и вообще в пень твой сервис - посмотрю в онлайн кинотеатре дома

короч, еще раз - ты решаешь проблему, которая появилась у тебя из того, как ты организовал UI и работу с оным. Внезапно у тебя реализация клиента влияет на бизнес

при этом мои варианты ты называешь негибкими - и в этом я вижу проблему

Maksim
14.10.2018
13:03:14
проблеме при этом не первый день и её давно уже решили

Дмитрий
14.10.2018
13:12:34
при этом мои варианты ты называешь негибкими - и в этом я вижу проблему
Вопрос еще не закрыт, продолжим потом, мне стало интересно)

Aleh
14.10.2018
13:31:21


Sergey
14.10.2018
13:34:05
сначала была протокурица, потом курирое яйцо и потом уже курица.

First
14.10.2018
13:34:11
Пхпшники, вас можно поздравить?

Rfc с типами на свойство приняли

Sergey
14.10.2018
13:34:42
ты осоздал, мы уже неделю назад это дело обмывали

First
14.10.2018
13:34:51
А де мои одинарные кавычки?

Sergey
14.10.2018
13:35:19
всеравно с типами в пыхе все плохо и будет плохо и ничего не поменяется

Google
First
14.10.2018
13:36:08
Это те, которые встроенны в ядро и не умеют ничего?

Sergey
14.10.2018
13:36:37
типа всеравно придется писать что-то типа /** * @var Post[] */ private array $posts;

First
14.10.2018
13:36:52
А ты снова про дженерики)

Меня больше угнетает то, что у типов нету объектов

Sergey
14.10.2018
13:37:14
ну просто возможность задать тип для проперти у меня и так была - а возможность проверять в рантайме мне нах не нужна

Sergey
14.10.2018
13:38:38
Вряд ли они тебе закинут их до 8ой
проблема - желание проверять типы в рантайме. Потому что они хотят их хоть где-нибудь проверять)

а не просто синтаксис

First
14.10.2018
13:39:08
Мне вот недавно пришлось снова на пхп пописать денек, как же я горел ?

Aleh
14.10.2018
18:25:03
Плохому танцору яйца мешают
И кирзовые сапоги еще бывает совсем не помогают гранд батман делать

Yury
14.10.2018
20:39:13
все это - прекондишены а не инварианты.
Блин я все пропустил, но было интересно прочитать дискуссию. Уже поздно, но напишу сейчас. Вот мой кейс: Есть рестораны, у них менеджеры. Менеджеры заказывают курьеров. Курьер принимает заказ через телеграм бота. Но вот инвариаты, которые должны не должны провалиться перед действием: 1. Курьер должен быть в XXX минутах от места куда нужно прибыть, на момент когда он принимает заказ. 2. Он должен состоять в одной группе с рестораном (менеджер этого сервиса может исключить курьера из группы, уже после того как курьеру прилетело уведомление о заказе) 3. Банально проверить не взял ли уже другой курьер этот же заказ. => нужно, чтобы курьер мог понять все причины, из-за чего у него не получилось взять заказ. Возможно логично, что ему не нужно знать более одной причины. НО тут требование заказчика. Или вот возможно более явный пример: Человек оформляет перевод, нужно проверить что тот кому он переводит не заблокирован и разрешает переводы к себе а также проверить, что оставшегося после перевода баланса хватить чтобы погасить ежемесячные расходы(тут не буду углубляться, эта общая суть) В целом идея, что проверка - это не инвариант - наверное правильная мысль. Типа по какому нибудь CQRS мы можем из команды ничего не возвращать, только прошла операция или нет. А уже потом делать запрос на предмет что именно не так.

.

Sergey
14.10.2018
20:41:25
Блин я все пропустил, но было интересно прочитать дискуссию. Уже поздно, но напишу сейчас. Вот мой кейс: Есть рестораны, у них менеджеры. Менеджеры заказывают курьеров. Курьер принимает заказ через телеграм бота. Но вот инвариаты, которые должны не должны провалиться перед действием: 1. Курьер должен быть в XXX минутах от места куда нужно прибыть, на момент когда он принимает заказ. 2. Он должен состоять в одной группе с рестораном (менеджер этого сервиса может исключить курьера из группы, уже после того как курьеру прилетело уведомление о заказе) 3. Банально проверить не взял ли уже другой курьер этот же заказ. => нужно, чтобы курьер мог понять все причины, из-за чего у него не получилось взять заказ. Возможно логично, что ему не нужно знать более одной причины. НО тут требование заказчика. Или вот возможно более явный пример: Человек оформляет перевод, нужно проверить что тот кому он переводит не заблокирован и разрешает переводы к себе а также проверить, что оставшегося после перевода баланса хватить чтобы погасить ежемесячные расходы(тут не буду углубляться, эта общая суть) В целом идея, что проверка - это не инвариант - наверное правильная мысль. Типа по какому нибудь CQRS мы можем из команды ничего не возвращать, только прошла операция или нет. А уже потом делать запрос на предмет что именно не так.
1-ое и 2ое вроде как прекондишены а не инварианты. 3-ее - можно проверить но опять же будут ситуации с конкурентным доступом которые ты никак нормально не разрулишь.

Yury
14.10.2018
20:43:05
1-ое и 2ое вроде как прекондишены а не инварианты. 3-ее - можно проверить но опять же будут ситуации с конкурентным доступом которые ты никак нормально не разрулишь.
Почему прекондишены, что это значит? Мы же должны проверить эти все три условия перед изменением состояния, верно? Это все должно происходить при одном и том же снапшоте состояния жи.

конкурентным доступом которые ты никак нормально не разрулишь. - блокировки?

Google
Sergey
14.10.2018
20:46:48
и можно ли говорить о инвариантах если состояние не меняется?

Yury
14.10.2018
20:47:44
и можно ли говорить о инвариантах если состояние не меняется?
Ну мы проверяем все три инварианта, когда делаем снап состояния на момент запроса. Если три инварианта выполяются мы меняем стейт

вот у тебя есть пред условия, пост условия и инварианты. Что есть что?
Вообще множественные инварианты (инвариант как бы по сути не один, но проверок для его удовлетворения несколько) на мой взгляд таких случаев много оч много. Например вот у Вернона есть такие: https://github.com/VaughnVernon/IDDD_Samples/blob/05d95572f2ad6b85357b216d7d617b27359a360d/iddd_collaboration/src/main/java/com/saasovation/collaboration/domain/model/forum/Forum.java#L79 Я пытаюсь понять, как ты отличаешь пред условия, пост условия и инварианты, на примерах, что есть что и почему? Для меня это все инварианты

Sergey
14.10.2018
21:01:29
инварианты - это когда у нашего объекта есть состояние. И эти самые инварианты - это некие предикаты (утверждения, условия) которые описывают непротиворечивый стэйт этого объекта. Помимо инвариантов (которые относятся к всему объекту, или системе) есть еще прекондишены и пост кондишены (пред условие - на вход нам нужно подать айдишку юзера, который существует, не заблокирован и все такое. Пост условие - если все хорошо - состояние поменяется определенным образом). То есть само по себе изменение состотяние - это уже пост условие. Главное что бы при изменении состояния все предикаты описывающие инварианты оставались истинными.

Давай теперь посмотрим на твой пример. У нас есть три предиката, которые должны быть истины на момент заказа курьера: - курьер должен быть в XXX минутах от места - курьер должен состоять в группе - курьер должен быть свободен Даже если мы каким-то образом проверим все три условия и выплюнем менеджеру ошибку что мол одно из условий нарушено - мы никак не сможем гарантировать что за тот промежуток времени состояние не поменяется еще раз и не произойдет еще ошибки. Потому я считаю что глупо пытаться оптимизировать эту часть работы, ибо в целом никому от этого удобнее в реальности не будет. Одна ошибка или все три - результат для менеджера один и тот же - он не может передать заказ этому курьеру. В целом мы всегда можем проверить все три условия отдельно, оставляя лишь пограничные ситуации: - когда курьер вот-вот отъедит слишком далеко - курьер вот-вот примет заказ - курьера вот-вот исключат из группы (как по мне самый маловероятный сценарий из трех) Что бы все три ивента произошли одновременно (или два из трех) - менеджеру твоему должно сильно Не повести. А если мы говорим о хэппи флоу - можно отдельно проверить все три условия и выплюнуть менеджеру состояние. В целом, мы вообще не должны отображать ему варианты, которые приведут к нежелательному результату. Синхронизировать стэйт на клиенте у менеджера что бы тот видел сколько кому ехать, кто стал занятым и т.д. Все что бы уменьшить окно по времени когда могут возникать эти вот пограничные ситуации.

Yury
14.10.2018
21:07:50
инварианты - это когда у нашего объекта есть состояние. И эти самые инварианты - это некие предикаты (утверждения, условия) которые описывают непротиворечивый стэйт этого объекта. Помимо инвариантов (которые относятся к всему объекту, или системе) есть еще прекондишены и пост кондишены (пред условие - на вход нам нужно подать айдишку юзера, который существует, не заблокирован и все такое. Пост условие - если все хорошо - состояние поменяется определенным образом). То есть само по себе изменение состотяние - это уже пост условие. Главное что бы при изменении состояния все предикаты описывающие инварианты оставались истинными.
на вход нам нужно подать айдишку юзера, который существует, не заблокирован и все такое. - ты как бы это делаешь не в домене или в отдельном запросе? Все-таки я не пойму чем отличается инварианты от прекондишенов. Вот на моем примере с курьерами, почему гелолокация и пристуствие в группе это прекондишены, а не инварианты?

Sergey
14.10.2018
21:07:53
то есть так же как ты бы делал непосредственно при изменении - ты можешь предоставить отдельные методы для проверки каждого из условий.

Давай теперь посмотрим на твой пример. У нас есть три предиката, которые должны быть истины на момент заказа курьера: - курьер должен быть в XXX минутах от места - курьер должен состоять в группе - курьер должен быть свободен Даже если мы каким-то образом проверим все три условия и выплюнем менеджеру ошибку что мол одно из условий нарушено - мы никак не сможем гарантировать что за тот промежуток времени состояние не поменяется еще раз и не произойдет еще ошибки. Потому я считаю что глупо пытаться оптимизировать эту часть работы, ибо в целом никому от этого удобнее в реальности не будет. Одна ошибка или все три - результат для менеджера один и тот же - он не может передать заказ этому курьеру. В целом мы всегда можем проверить все три условия отдельно, оставляя лишь пограничные ситуации: - когда курьер вот-вот отъедит слишком далеко - курьер вот-вот примет заказ - курьера вот-вот исключат из группы (как по мне самый маловероятный сценарий из трех) Что бы все три ивента произошли одновременно (или два из трех) - менеджеру твоему должно сильно Не повести. А если мы говорим о хэппи флоу - можно отдельно проверить все три условия и выплюнуть менеджеру состояние. В целом, мы вообще не должны отображать ему варианты, которые приведут к нежелательному результату. Синхронизировать стэйт на клиенте у менеджера что бы тот видел сколько кому ехать, кто стал занятым и т.д. Все что бы уменьшить окно по времени когда могут возникать эти вот пограничные ситуации.
опять же - в случае чего ты даже блокировками не много чего сможешь добиться поскольку курьер может быть в пределах досигаемости а потом вжух так, все ок, транзакция завершена, вот только интернет у курьера лагнул и оказалось что он уже дальше чем нужно. Скорее всего в этой ситуации твоя система не будет ничего отменять пост фактум, да?

Yury
14.10.2018
21:11:53
Пока оставим что нужно уведомлять о результате всех трех проверок инварианта

Yury
14.10.2018
21:14:45
да, согласен. Ну проверяй. Но твой вопрос был относительно списка ошибок.
По списку да, тут наверное действительно не очень нужно это - согласен. Тем более что можно потом сделать проверку уже query запросом. Буду искать еще примеры где мне нужно было вернуть сразу весь список ошибок, без прекондишенов. Если найду отпишу :)

Sergey
14.10.2018
21:14:52
я выше описал почему считаю это бесполезной затеей. Но тебе никто не мешает сделать 3 проверки и если одна из них зафэйлилась кинуть общее исключение.

которое может уже включать в себя информацию о результатах всех трех ошибок

Yury
14.10.2018
21:15:34
Я только думал как это технически сделать, чтобы норм выглядело

res += isValidFirstCond() res += isValidSecondCond() res += isValidThirdCond() if(res.hasError()) throw ArgException(res.errors) Как то не оч наверное?

Sergey
14.10.2018
21:17:20
почему нет?

но в целом - я не сталкивался с такими потребностями

Google
Yury
14.10.2018
21:18:01
почему нет?
Когда кода больше с доменными понятиями - то как будто это усложняет понимание и читаемость самой предметной области

Но хотя жертвовать приходится чем то если это реально нужно в редких случаях

Спасибо

Еще последнее

ну то есть список ошибок - это можно на уровне валидации входящих данных проверить. Дальше уже списка ошибок быть не может
ну то есть список ошибок - это можно на уровне валидации входящих данных проверить. Вот тут можешь описать подробнее как ты это делаешь? Например та же история с email который мы потом создаем VO Email c проверкой при создании.

Yury
14.10.2018
21:20:08
А потом создаем VO Name и тоже првоеряем при создании

Yury
14.10.2018
21:20:37
говно всегда можно вынести в приватный метод
Я больше про имена, по типу где res и res.hasError

Sergey
14.10.2018
21:20:42
function foo(name: Name, email: Email)

хз) домен твой чистым абсолютно никогда не будет) сам понимаешь)

Yury
14.10.2018
21:21:45
ну вот email с проверкой при создании - это из вне, оно уже на вход приходит все такое валидное и готовое юзаться
Как мне вывести ошибки обо всех и Name и Email? Те получается попробовали создать VO Name зафейлились, сохранили ошибку, попробовали Name создать, опять зафейлились, потом вывели все эти ошибки? Не по уродски?

Sergey
14.10.2018
21:21:53
вот если бы ты DSL писал свой - то можно было бы сделать чистый домен.

а так у тебя всегда будут технические штуки в коде

Yury
14.10.2018
21:22:35
нада учить Скалу)

Страница 778 из 785