Комментарии 6
НЛО прилетело и опубликовало эту надпись здесь
На мой взгляд получилось очень странно и мимо.
Там же, чуть дальше, рабочая группа в результате обсуждения пришла к следующему:
— коллекция, это тоже вещь, потому пункты 2 и 3 это одно и то же.
— поскольку объекты всегда передаются по ссылке, пункт 1 это лишь частный случай пункта 2
— для пункта 4 добавить интерфейс
В результате разработчик (Б) по сигнатуре видит все необходимое.
В описательной части стандарта psr упоминаются следующие варианты использования:
1. одностороннее уведомление — «Я сделал что-то, если тебе интересно»
2. улучшение объекта — «Вот вещь, пожалуйста, измените её, прежде чем, я что-то с ней сделаю»
3. коллекция — «Дайте мне все ваши вещи, чтобы я мог что-то сделать с этим списком»
4. альтернативная цепочка — «Вот вещь, первый из вас кто справится с этим, сделает это, затем остановиться»
Там же, чуть дальше, рабочая группа в результате обсуждения пришла к следующему:
— коллекция, это тоже вещь, потому пункты 2 и 3 это одно и то же.
— поскольку объекты всегда передаются по ссылке, пункт 1 это лишь частный случай пункта 2
— для пункта 4 добавить интерфейс
StoppableEventInterface
В результате разработчик (Б) по сигнатуре видит все необходимое.
+2
Поскольку, уже второй комментарий с упоминанием, передачи объекта по ссылке.
Это верно, только когда передаваемые объекты содержат методы изменения данных. В случае простого DTO объекта, изменить, его нельзя.
Пример:
Это только оповещение, без возможности изменения переданного объекта.
Тут, явно описано, что обработчик может изменить объект, или даже подменить его реализацию.
И повторюсь, интерфейс CustomerNameInterface при разработке уже есть в системе, в описанном способе дополнительный объект «сахар» CustomerEvent не нужен.
поскольку объекты всегда передаются по ссылке, пункт 1 это лишь частный случай пункта 2
Это верно, только когда передаваемые объекты содержат методы изменения данных. В случае простого DTO объекта, изменить, его нельзя.
Пример:
interface CustomerNameInterface {
public function firstName(): string;
public function lastName(): string;
public function middleName(): ?string;
}
interface customerNameChangedListener {
public function onCustomerNameChange(
int $customerId,
CustomerNameInterface $customerName
);
}
Это только оповещение, без возможности изменения переданного объекта.
interface customerNameBeforeChangeListener {
public function onBeforeCustomerNameChange(
int $customerId,
CustomerNameInterface $customerName
): CustomerNameInterface
}
Тут, явно описано, что обработчик может изменить объект, или даже подменить его реализацию.
И повторюсь, интерфейс CustomerNameInterface при разработке уже есть в системе, в описанном способе дополнительный объект «сахар» CustomerEvent не нужен.
0
Это верно, только когда передаваемые объекты содержат методы изменения данных. В случае простого DTO объекта, изменить, его нельзя.
Наверное я еще не проснулся, и ннада больше кофе. Или вы действительно предлагаете «для изменения неизменяемых объектов просто используем подмену объектов»? Тогда не понятно, зачем у вас вообще методы у объекта — сделайте просто все свойства пабликами.
При этом все еще не ясно, каким образом вы собираетесь изменять этот объект внутри листенера. Максимум что вы можете — вытащить имя другого кастомера и вернуть его вместо оригинала.
И повторюсь, интерфейс CustomerNameInterface при разработке уже есть в системе, в описанном способе дополнительный объект «сахар» CustomerEvent не нужен.
CustomerNameInterface — описывает конкретно этот объект.
CustomerEvent — в свою очередь описывает событие, и в тех редких случаях, когда он не нужен — можно вообще обойтись без событий. В типичной же системе у вас будет примерно следующее
interface LogChangesEvent {
public function getObjectIdentifier(): string;
public function getOldValue(): JsonSerializable;
public function getNewValue(): JsonSerializable;
}
interface SmsNotifyEvent {
public function getRecipient(): string;
public function getText(): string;
}
interface CustomerNameChangedEvent implements SmsNotifyEvent, LogChangesEvent {
public function getCustomerName(): CustomerNameInterface;
}
Ну и сообветственно набор листенеров, которые слушают тот же SmsNotifyEvent — они ничего не знают ни про кастомера, ни про его CustomerNameInterface.
0
По моему мнению, это обсуждение начинает скатываться в «холивар» по реализациям. Что, в свою очередь уведет от сути. Я специально в статье обходил, моменты, которые могут свести все к разнообразным «холиварам» не по теме.
В приведенном Вами примере, больше вопросов чем ответов. «Холиварных», вопросов.
Вопросы:
По описанному вами коду, я вижу 3 разных задачи:. Изменение имени, смс информирование, и логирование. При этом основной задачей является изменение имени. Остальные второстепенные.
По вашему коду получаются связи: Клиент зависит от смс и логирования, что по мне в корне не корректно, так как связь должна быть обратной. смс и логирования может не быть, это второстепенный функционал.
Исходя из этого смс и логирования, должны быть слушателем, а не частью события на кейсе изменения имени клиента.
В приведенном Вами примере, больше вопросов чем ответов. «Холиварных», вопросов.
Вопросы:
- Интерфейс CustomerNameChangedEvent, какому пакету (модулю, банду, скопу) принадлежит? Сервису, который отвечает за изменение данных клиента?
- Интерфейс SmsNotifyEvent, какому пакету (модулю, банду, скопу) принадлежит? Сервису, который отвечает за sms отправку?
- Интерфейс LogChangesEvent, какому пакету (модулю, банду, скопу) принадлежит? Сервису, который отвечает за логирование?
По описанному вами коду, я вижу 3 разных задачи:. Изменение имени, смс информирование, и логирование. При этом основной задачей является изменение имени. Остальные второстепенные.
По вашему коду получаются связи: Клиент зависит от смс и логирования, что по мне в корне не корректно, так как связь должна быть обратной. смс и логирования может не быть, это второстепенный функционал.
Исходя из этого смс и логирования, должны быть слушателем, а не частью события на кейсе изменения имени клиента.
0
Так давайте не будем все скатывать в холивар по реализациям. Честно говоря мне просто было лень думать над названиями классов, так что я ткнул первое что пришло в голову.
Ну пусть это будет система смс рассылок, и этот функционал будет обязательным. Связь же у нас исключительно через реализацию интерфейсов, так что не вижу в этом ничего противоестественного. Так предлагаю остановиться на том что у нас в системе есть модуль в котором описаны ключевые интерфейсы связей между модулями.
В любом случае суть не в этом. Сейчас мы имеем два варианта реализации
— ваш пример, в котором при добавлении логирования мы должны будем подписаться на сотню эвентов смены имени/адреса/и т.д., зато все модули абсолютно независимы.
— мой пример, где про добавлении логирования нужно подписаться только на
На мой взгляд, в зависимости от системы, любой из этих вариантов имеет право на жизнь. А обсуждать какой из них лучше я даже не предлагаю.
Тем не менее — эта часть ветки действительно уходит в тупик, т.к. мы перешли к обсуждению лишь части комментария, суть которого была привести пример когда «дополнительный объект «сахар» CustomerEvent» таки нужен.
Вообще, перечитав статью, возникло ощущение что вас просто напрягает древняя реализация эвентов в zf, но Вы зачем-то приплели сюда еще и psr-14, который вообще по сути только про диспетчер. Посмотрите например на реализацию тут github.com/phly/phly-event-dispatcher — позволяет все что вы хотите, и без костылей типа двух разных методов в диспетчере.
По вашему коду получаются связи: Клиент зависит от смс и логирования, что по мне в корне не корректно, так как связь должна быть обратной. смс и логирования может не быть, это второстепенный функционал.
Ну пусть это будет система смс рассылок, и этот функционал будет обязательным. Связь же у нас исключительно через реализацию интерфейсов, так что не вижу в этом ничего противоестественного. Так предлагаю остановиться на том что у нас в системе есть модуль в котором описаны ключевые интерфейсы связей между модулями.
В любом случае суть не в этом. Сейчас мы имеем два варианта реализации
— ваш пример, в котором при добавлении логирования мы должны будем подписаться на сотню эвентов смены имени/адреса/и т.д., зато все модули абсолютно независимы.
— мой пример, где про добавлении логирования нужно подписаться только на
LogChangesEvent
, но при этом модули зависят от общего модуля с описанием интерфейсов.На мой взгляд, в зависимости от системы, любой из этих вариантов имеет право на жизнь. А обсуждать какой из них лучше я даже не предлагаю.
Тем не менее — эта часть ветки действительно уходит в тупик, т.к. мы перешли к обсуждению лишь части комментария, суть которого была привести пример когда «дополнительный объект «сахар» CustomerEvent» таки нужен.
Вообще, перечитав статью, возникло ощущение что вас просто напрягает древняя реализация эвентов в zf, но Вы зачем-то приплели сюда еще и psr-14, который вообще по сути только про диспетчер. Посмотрите например на реализацию тут github.com/phly/phly-event-dispatcher — позволяет все что вы хотите, и без костылей типа двух разных методов в диспетчере.
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Альтернативный подход к подписке на события, или а так ли нужен EventObject