
Sergey
23.03.2018
20:00:57
ну или билдер да)

Andrey
23.03.2018
20:01:16
Го ещё третье наброшу

Timur
23.03.2018
20:01:55

Google

Andrey
23.03.2018
20:02:00
Нах в симфе сделали в ивенте stopPropagation. Причём без интерфейса

Sergey
23.03.2018
20:02:47
Плюс можно пропускать что хочешь
такая позиция говорит о том что ты подменяешь понятие "гибкость" на "отсутствие ограничений". Отсутствия ограничения приводят к некорректному использованию, плодятся баги, нарушается принцип KISS (который про то что бы что-то что ты делаешь было просто и удобно использовать). Теряется семантика (сложнее разбираться потом что и зачем - не проблема если все что нам надо это заменить стэйт)

Alan
23.03.2018
20:03:36
или addLetter()

Sergey
23.03.2018
20:04:06

Елнур
23.03.2018
20:04:15
Создавать сущности для леттера не обязательно, поскольку уже есть php тип как string

Konstantin
23.03.2018
20:05:07

Sergey
23.03.2018
20:05:19
По мне, такой вариант вполне логичен
я бы еще is moderated вынес из этой сущности, isAlive тебе lifetime скажет, тип - можно заменить на тип (композицией), страну проживания - там частенько не только страна, но список стран где жил и все такое...)

Konstantin
23.03.2018
20:05:23
но идея четкая, вдруг я не хочу всю энтити менять а только букву изменить

Елнур
23.03.2018
20:05:24
Два переменных string, которые в купе означают имя человека - Name
Тестировать легче

Google

Sergey
23.03.2018
20:05:48

Konstantin
23.03.2018
20:06:22
setLetterAt(Letter $letter, Index $index) @throws IllegalArgumentException
а внутри еще пару assert

Елнур
23.03.2018
20:06:27
И когда с проектом имеете дело несколько лет, не забудете, какие поля имеют общую логику
То есть, семантику

Sergey
23.03.2018
20:06:57

Alan
23.03.2018
20:07:17
а внутри еще пару assert
мб тебе и не все имя нужно доставать а только first name тогда надо сделать getLetter и в цикле извлекать буквы до пробела где то там снаружи и так всю жизнь )))

Konstantin
23.03.2018
20:07:41
да кароче
вот кейс рили
в контроллер прилетел dto который заранее где то там создан из реквеста. роут есть PUT, т.е. апдейт сущности.
как теперь заменить сущность имея на руках дто?
код плиз
только давайте без группировки VO
там 10 полей от силы

Timur
23.03.2018
20:09:42

Sergey
23.03.2018
20:10:13

Timur
23.03.2018
20:10:23

Sergey
23.03.2018
20:10:31
а ну да, я забыл что вся логика в контроллерах

Alan
23.03.2018
20:11:55
мне например сейчас надо полное имя показывать на англ версии транслитерированным (тк чуваки из бразилии не поймут что за Иван Иванов выиграл штуковину у нас на сайте) и Name мне может вернуть новый self с транслитерированными буквами

Konstantin
23.03.2018
20:12:09
а потом такой сходил за кофе а там кто то уже вторую сотню классов дописывает )
и все маленькие и нужные

Google

Sergey
23.03.2018
20:12:21

Timur
23.03.2018
20:12:21

Konstantin
23.03.2018
20:12:33
пока что в районе 50 что ли
это примерно по 10 на роут
но еще не вечер

Sergey
23.03.2018
20:13:10
вот например
из твоего снипета
>setBirthdate('13-08-1899')
->setDieddate('29-04-1980')
->setIsAlive(false)
кто будет выяснять жив ли чувак или нет - это просто галочка и даты ни на что не влияют?

Konstantin
23.03.2018
20:14:39
isAlive тут лишнее т.к. его и так можно вычислить

Sergey
23.03.2018
20:15:00

Konstantin
23.03.2018
20:15:31
значит diedDate не нужен
т.к. будет ставиться в тот момент когда меняется isAlive

Sergey
23.03.2018
20:16:16
зачем усложнять?)

Timur
23.03.2018
20:16:25
isAlive тут лишнее т.к. его и так можно вычислить
Это не имеет значения, я аттрибуты от балды напридумывал, суть в том, что их может быть очень много и не все надо вбивать сразу. Может статься ты создаешь какой-то объект, заполняешь "наполовину", что-то делаешь с ним, и потом дополняешь, например жив он или нет.

Konstantin
23.03.2018
20:16:31
ну я и говорю зачем усложнять - оставь один параметр какой та

Sergey
23.03.2018
20:16:31
я хочу услышать ответ в стиле "я хочу просто засовывать в базу json который мне приходит с клиента"

Konstantin
23.03.2018
20:17:01

Google

Timur
23.03.2018
20:17:10

Sergey
23.03.2018
20:17:17

Timur
23.03.2018
20:17:21
Для этого чата придумал первое что пришло вг олову
Между этим я пью чай

Sergey
23.03.2018
20:19:31
Между чем "этим"?
логика есть между принял данные и сохранил? не валидация данных - а именно логика какая-то, ограничения и т.д
ну то есть предположим у меня есть хрень которая позволяет мне напрямую с клиента писать в базу без какой либо необходимости писать бэкэнд и я могу все эти тупые случаи с крудом через него делать

Konstantin
23.03.2018
20:23:27
а если например сначала напихал везде VO а потом надо их разбить помельче
такое бывает не?

Admin
ERROR: S client not available

Sergey
23.03.2018
20:23:51
иногда
реальность такова что чем сложнее проект тем меньше вероятность что ты сделаешь "ок" с первого раза.
потому читать книжку фаулера про рефакторинг надо всем и каждому и чем раньше тем лучше
если смущает что для простых хреновин надо много делать - не проблема, смысл в том что бы простые хрени отдать на откуп простым решениям (круд напрямую в базу без необходимости тебя дергать). А тебе тогда останется только то что посложнее.

Konstantin
23.03.2018
20:27:11
надо не просто сделать а сделать чтобы можно было доработать
да, не сомневаюсь, где то у крутых пацанов bleeding edge technology разработки ) но я сомневаюсь что такие ребята будут поддерживать

Sergey
23.03.2018
20:28:05
надо не просто сделать а сделать чтобы можно было доработать
да, все верно. И я допускаю что с сеттерами и геттерами так можно сделать, но.... я просто не вижу в этом смысла и уж тем более считаю вредным делать так по умолчанию. В определенных ситуациях ничего лучше нету) но это как исключение нежели обычная практика...

Konstantin
23.03.2018
20:28:09
там скорей всего будут какие нибудь пацаны из соседнего подъезда

Andrey
23.03.2018
20:28:48

Sergey
23.03.2018
20:29:12

Google

Sergey
23.03.2018
20:29:45
но я с тобой согласен что это "странно" потому для своих ивентов я юзаю свой диспатчер который делает честный pub/sub и который нельзя "остановить"
еще нюанс - приоритеты листенеров - с точки зрения управления зависимостями это полнейший рак
но щито поделать)


Timur
23.03.2018
20:31:25
т.к. будет ставиться в тот момент когда меняется isAlive
Вот еще один случай, когда нужен сеттер. Вытащил сущность из бд, вызвал $user->setDieddate(), внутри которого сразу устанавливается или снимается флаг isAlive.
Или может статься, что проект разросся до огромных размеров, а ты везде использовал прямой доступ к аттрибутам класса, без геттера, а потом выяснилось, что при вызове $user->getGroup() сначала надо проверить, указана ли группа юзера напрямую, если нет, то взять группу из класса этого юзера, если и там нет, то взять дефолтную группу школы, к котрой принадлежит юзер. Тогда пришлось бы искать все случаи прямого доступа и заменять их на вызов геттера. Это настоящий use case из моего проекта.
public function getGroup()
{
if ($this->group) {
return $this->group;
}
if ($this->getClass()) {
if ($this->getClass()->getGroup()) {
return $this->getClass()->getGroup();
}
}
//just take the first one
$groups = $this->getSchool()->getGroups();
if (count($groups)) {
return $groups->first();
}
return null;
}
Я не понимаю, что Сергей хочет мне доказать, когда целесообразность использования геттеров и сеттеров с самого начала очевидна.


Konstantin
23.03.2018
20:32:10
Вот еще один случай, когда нужен сеттер. Вытащил сущность из бд, вызвал $user->setDieddate(), внутри которого сразу устанавливается или снимается флаг isAlive.
Или может статься, что проект разросся до огромных размеров, а ты везде использовал прямой доступ к аттрибутам класса, без геттера, а потом выяснилось, что при вызове $user->getGroup() сначала надо проверить, указана ли группа юзера напрямую, если нет, то взять группу из класса этого юзера, если и там нет, то взять дефолтную группу школы, к котрой принадлежит юзер. Тогда пришлось бы искать все случаи прямого доступа и заменять их на вызов геттера. Это настоящий use case из моего проекта.
public function getGroup()
{
if ($this->group) {
return $this->group;
}
if ($this->getClass()) {
if ($this->getClass()->getGroup()) {
return $this->getClass()->getGroup();
}
}
//just take the first one
$groups = $this->getSchool()->getGroups();
if (count($groups)) {
return $groups->first();
}
return null;
}
Я не понимаю, что Сергей хочет мне доказать, когда целесообразность использования геттеров и сеттеров с самого начала очевидна.
брат я с тобой
я бодался но меня забодали )


Andrey
23.03.2018
20:34:05
но щито поделать)
да вот и меня сильно удивляет. 4тая мажорная версия, многолет, многолюдей, но всё ещё остаются такие вещи
ну плиз, хотя бы не базовый класс без интерфейса
жирнющий ивент диспетчер (жирный интерфейс)
да, можно сделать свой интерфейс диспетчера, под которым спрятались адаптер


Sergey
23.03.2018
20:35:18
Вот еще один случай, когда нужен сеттер. Вытащил сущность из бд, вызвал $user->setDieddate(), внутри которого сразу устанавливается или снимается флаг isAlive.
Или может статься, что проект разросся до огромных размеров, а ты везде использовал прямой доступ к аттрибутам класса, без геттера, а потом выяснилось, что при вызове $user->getGroup() сначала надо проверить, указана ли группа юзера напрямую, если нет, то взять группу из класса этого юзера, если и там нет, то взять дефолтную группу школы, к котрой принадлежит юзер. Тогда пришлось бы искать все случаи прямого доступа и заменять их на вызов геттера. Это настоящий use case из моего проекта.
public function getGroup()
{
if ($this->group) {
return $this->group;
}
if ($this->getClass()) {
if ($this->getClass()->getGroup()) {
return $this->getClass()->getGroup();
}
}
//just take the first one
$groups = $this->getSchool()->getGroups();
if (count($groups)) {
return $groups->first();
}
return null;
}
Я не понимаю, что Сергей хочет мне доказать, когда целесообразность использования геттеров и сеттеров с самого начала очевидна.
> вызвал $user->setDieddate(), внутри которого сразу устанавливается или снимается флаг isAlive.
а если я переименую этот метод в died() то он останется сеттером?
> а ты везде использовал прямой доступ к аттрибутам класса, без геттера
Ты не понимаешь в чем проблема - проблема что тебе понадобился доступ к группам изначально. А так, например для UI, геттеры норм
> Я не понимаю, что Сергей хочет мне доказать
я ни в коем случае не хочу тебе доказать что "никогда не юзай геттеры/сеттеры". Это глупо, я сам ими пользуются часто. Я хочу что бы люди начали различать геттеры/сеттеры от просто методов и начали осознавать разницу, то как геттеры/сеттеры ломают инкапсуляцию, то как они повышают связанность и т.д.
Повторюсь для ясности - если ты берешь сущность и в рамках операции вызваешь один единственный сеттер, и все, операция завершилась - то в этом нет ничего плохого. Вопрос остается в семантике но и так сойдет. С точки зрения связанности и гибкости никакой разницы с сеттером ты это делаешь или без.
меня волнует только связанность, декомпозиция, гибкость кода, простота восприятия кода, удобство внесения изменений
все остальное - плевать в целом
если я хз как назвать метод и называю его setSomething() или doSomething() хотя понимаю что метод херовый - задачу то доделать надо - буду больше знать про фичу и смогу придумть норм название - переименую когда буду проходить рядом


Konstantin
23.03.2018
20:39:31
блин дак, доступ к голым проперти - это нарушение инкапсуляции, а вызов сеттера то почему вдруг стал нарушением инкапсуляции? )

Sergey
23.03.2018
20:39:44
но сама идея шаринга стэйта - не самая лучшая идея с точеи зрения поддерживаемого кода

Konstantin
23.03.2018
20:39:56
только потому что у элемента 10 переключалок вместо 3? )

Andrey
23.03.2018
20:40:26

Sergey
23.03.2018
20:41:05
первое очевидно не ок по причинам которые ты озвучил, второе тоже не ок потому что система полезной работы не совершает ибо не может взаимодействовать с внешним миром

Konstantin
23.03.2018
20:41:51
я понял под инкапсуляцией вы понимаете "мало методов"