Kirill
https://ru.wikipedia.org/wiki/%D0%A1%D0%B2%D0%BE%D0%B9%D1%81%D1%82%D0%B2%D0%BE_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5) https://learn.microsoft.com/ru-ru/dotnet/csharp/programming-guide/classes-and-structs/properties https://programm.ws/page.php?id=1061 etc
Михаил
гет + сет - это эмуляция свойств
а свойства это эмуляция get и set 🌚
Kirill
вот ещё https://habr.com/ru/articles/541308/
Stein
🧑🏻‍💻Организую инвайт в чаты, рассылку в лс и по чатам, сбор ца❗️ 📮Пишите в лс❗️
Kirill
Да мало ли как называется. Метод тоже можно функцией называть, а анонимку замыканием
Короче, срать как называешь, если понятно из контекста. Только когда начинаешь задавать вопросы на тему "а чем отличается", то как бы уже терминология важна
Kirill
Вот и ответ, что геттеры + сеттеры - это эмуляция свойств, а свойства и так уже есть на уровне языка
Kirill
А в случае доступа на чтение онли, то и полей выше крыши
Kirill
например в ДТО
Kirill
final readonly class UserInfoResponseDTO { public function __construct( public int $id, public string $name, public AvatarResponseDTO $avatar, // etc ) {} }
Михаил
Вот такая натация свойств ещё хороша (помимо то что меньше кода) тем что обработчики get и set вызова лежат рядом с полями Плюс у нас появляются строгое разделение методов и свойств
Kirill
final readonly class UserInfoResponseDTO { public function __construct( public int $id, public string $name, public AvatarResponseDTO $avatar, // etc ) {} }
а посоны начинают городить геттеры для таких кейсов, чтобы что?
Kirill
Когда нет readonly
тогда есть @readonly
Kirill
сейчас помечаешь, а потом ректором за 1 проход автоматом апаешь
Михаил
тогда есть @readonly
аттрибуты - это вилами по воде писано
Kirill
ну так-то да
Михаил
работает только в связке с ci-cd и хорошей ide
Kirill
но всё равно когда-то обновляться придётся
Vlad
тогда есть @readonly
это работает до того момента, когда ты начинаешь выносить код в вендор
Kirill
так что просто с расчётом на 8ой пых
Михаил
аннотации)
ой, да, забыл что мы в php
Михаил
phpstan отлавливает такое
правда чтоль? А я разве не это написал?
Vlad
это работает до того момента, когда ты начинаешь выносить код в вендор
и сразу же появляется соблазн у твоих потребителей
Михаил
Ребят, а есть ли какой-то гайд по тому как правильно заполнять Резюме для поиска работы Ну чтоб у hr и it отдела глаза не закатывались, но при этом что бы реально передать свой опыт + что бы автоматизации меня нашли?
Kirill
Вот такая натация свойств ещё хороша (помимо то что меньше кода) тем что обработчики get и set вызова лежат рядом с полями Плюс у нас появляются строгое разделение методов и свойств
Ну вот да, я полностью топлю за то, чтобы для данных использовать переменные (+ поля, свойства), а для действий - функции (+ методы, процедуры процедуры лучше вообще не использовать)
Михаил
Может находили какую-нибудь хорошую статью с примерами или сами писали
Kirill
Ну вот да, я полностью топлю за то, чтобы для данных использовать переменные (+ поля, свойства), а для действий - функции (+ методы, процедуры процедуры лучше вообще не использовать)
А когда меняется семантика - это уже не очень прикольно. Так что $user->getName(), который просто возвращает строку - это примерно тоже самое, что $user->emails[] = new Email(), который отправляет юзеру на почту письмо во время присваивания
Михаил
Ой, да кстати. Хорошо что напомнил Тут ближайшие лет 5 мы будем встречать то, что код одновременно использует свойство и get-set методы (из за легаси и библиотек) И глаза будут кровоточть. И возможно некоторые либы вообще не перейдут на это. Так что те, кто за единообразие или вообще будут использовать только get-set или будут использовать свойства, ну допустим в доменном слое.
Kirill
и по привычке пишу иногда всякие isSome(): bool
Михаил
Ребят, а есть ли какой-то гайд по тому как правильно заполнять Резюме для поиска работы Ну чтоб у hr и it отдела глаза не закатывались, но при этом что бы реально передать свой опыт + что бы автоматизации меня нашли?
@SerafimArts что насчёт этого скажешь. Я понимаю - ты в резюме просто пишешь "погуглите меня" и все вопросы отпадают. Но что делать простым смертным?
Kirill
но, к слову, в тех же шарпах такая же фигня
Kirill
там тоже иногда встречаю всякие Some.GetLength(), вместо Some.Length
Михаил
шарпах ещё есть _Length )
Михаил
хз, я никогда не заморачивался. Просто написал всё что делаю и умею и всё
ну вот я тоже не заморачиваюсь. Но блин - по ту сторону тоже люди. Они могут начать читать а потом "Да, да, да - мы поняли" А потом приходишь на интервью а тебя по резюме спрашивают и ты понимаешь что они его вообще не читали Значит не зацепило
Kirill
а в резюме что угодно можно понаписать
Kirill
код по-идее можно тоже стырить, но для этого нужен опыт чтоб понимать что норм, а что нет)
Михаил
В этом кстати печаль, если все проекты приватные или если проекты просто фановые
Kirill
так по фановым проектам тоже понятно
Aleksandr
ходят тут всякие
Aleksandr
бизнесмены мамкины
Юра
Александр
Нужен вариант "фриланс")
Юра
Ну те кто сами на себя могут пропустить этот опрос
Юра
Понятно что сам себя не будешь контролировать
Dmitriy
Что за контроль?
Юра
Работаешь ли ты или нет
Михаил
Работаешь ли ты или нет
ты ищешь вакансии и такое находил?
Михаил
или уже на работе такое?
kakoi-to-noob
Что за контроль?
Типа трекеры времени
Михаил
ну трекеры времени - это не проблема, это наоборот плюс. Когда задачку надо постфактум оценить, а ты такой "эээ, ну эта - 5 часов, а там часа 2 было, просто мозг не вывозит междневный трекинг"
Dmitriy
Контроль такой нафиг не нужен
Александр
Речь про скриншоты. Есть компании такие, они ставят проги которые делают, допустим, скриншот экрана каждые 2 минуты. Таким образом следят, чтобы только рабочими моментами занимался
Михаил
ну просто занимайтесь рабочими моментами каждые 2 минуты
Dmitriy
Да я понял, с таких компаний можно смело валить
Dmitriy
Такие компании и платят скорее всего копейки
Михаил
можно написать собственную утилиту, которая подписывается на хук скриншота и переопределяет сам скрин на, ну не знаю - фотку ide
Вадим
привет! подскажите филосовский вопрос. Вот есть у меня класс Price. В конструкторе он принимает значение цены Money. У класса есть метод addCoupon(Coupon $coupon), Купон суть сущность у которой есть $type. Тип может быть percent или amount, это enum. В зависимости от типа скидку по этому купону надо считать по-разному, соответственно. class PriceCalculator { public function calculatePrice(Product $product, Seller $seller, Coupon $coupon = null): Price { $price = $product->getPrice(); if (! is_null($coupon)) { $price->addCoupon($coupon); } return $price->applyTax($seller->getTax()); } } скидку расчитывает куркулятор скидок, их 2: процентный и количественный. final class Price implements \JsonSerializable { private function doApplyCoupon(): void { if (! isset($this->coupon)) { return; } $discountAmount = $this->coupon->getDiscountCalculator()->calculateDiscount($this->money); $value = $this->money->amount - $discountAmount->amount; $this->resultMoney = new Money(max($value, 0)); } } class Coupon { public function getDiscountCalculator(): DiscountCalculatorInterface { if ($this->type === CouponType::DiscountPercent) { return new PercentDiscountCalculator($this); } elseif ($this->type === CouponType::DiscountAmount) { return new AmountDiscountCalculator($this); } throw new \Exception('Unknown coupon type'); } } вопрос: меня смущает что я беру конкретный DiscountCalculator у сущности. Типа если для определения какой конкретный DiscountCalculator отдать потребуются ещё зависимости придётся их инжектить както в сущность. посоветуйте пожалуйста как лучше сделать
Nikolay
привет! подскажите филосовский вопрос. Вот есть у меня класс Price. В конструкторе он принимает значение цены Money. У класса есть метод addCoupon(Coupon $coupon), Купон суть сущность у которой есть $type. Тип может быть percent или amount, это enum. В зависимости от типа скидку по этому купону надо считать по-разному, соответственно. class PriceCalculator { public function calculatePrice(Product $product, Seller $seller, Coupon $coupon = null): Price { $price = $product->getPrice(); if (! is_null($coupon)) { $price->addCoupon($coupon); } return $price->applyTax($seller->getTax()); } } скидку расчитывает куркулятор скидок, их 2: процентный и количественный. final class Price implements \JsonSerializable { private function doApplyCoupon(): void { if (! isset($this->coupon)) { return; } $discountAmount = $this->coupon->getDiscountCalculator()->calculateDiscount($this->money); $value = $this->money->amount - $discountAmount->amount; $this->resultMoney = new Money(max($value, 0)); } } class Coupon { public function getDiscountCalculator(): DiscountCalculatorInterface { if ($this->type === CouponType::DiscountPercent) { return new PercentDiscountCalculator($this); } elseif ($this->type === CouponType::DiscountAmount) { return new AmountDiscountCalculator($this); } throw new \Exception('Unknown coupon type'); } } вопрос: меня смущает что я беру конкретный DiscountCalculator у сущности. Типа если для определения какой конкретный DiscountCalculator отдать потребуются ещё зависимости придётся их инжектить както в сущность. посоветуйте пожалуйста как лучше сделать
Не выносить логику калькуляции в сторонний класс, а сделать там, где больше всего данных лежит, которые используются в калькуляции, то есть в Price
Nikolay
а вдруг завтра купон будет применяться не только к цене товара но и ко всему чеку
Когда это понадобится, не будет сложности доработать. Сейчас калькулятор вообще никак не связан с Coupon
Вадим
Когда это понадобится, не будет сложности доработать. Сейчас калькулятор вообще никак не связан с Coupon
Ну он связан с купоном так что в зависимости от типа купона создаётся разный калькулятор
Юра
привет! подскажите филосовский вопрос. Вот есть у меня класс Price. В конструкторе он принимает значение цены Money. У класса есть метод addCoupon(Coupon $coupon), Купон суть сущность у которой есть $type. Тип может быть percent или amount, это enum. В зависимости от типа скидку по этому купону надо считать по-разному, соответственно. class PriceCalculator { public function calculatePrice(Product $product, Seller $seller, Coupon $coupon = null): Price { $price = $product->getPrice(); if (! is_null($coupon)) { $price->addCoupon($coupon); } return $price->applyTax($seller->getTax()); } } скидку расчитывает куркулятор скидок, их 2: процентный и количественный. final class Price implements \JsonSerializable { private function doApplyCoupon(): void { if (! isset($this->coupon)) { return; } $discountAmount = $this->coupon->getDiscountCalculator()->calculateDiscount($this->money); $value = $this->money->amount - $discountAmount->amount; $this->resultMoney = new Money(max($value, 0)); } } class Coupon { public function getDiscountCalculator(): DiscountCalculatorInterface { if ($this->type === CouponType::DiscountPercent) { return new PercentDiscountCalculator($this); } elseif ($this->type === CouponType::DiscountAmount) { return new AmountDiscountCalculator($this); } throw new \Exception('Unknown coupon type'); } } вопрос: меня смущает что я беру конкретный DiscountCalculator у сущности. Типа если для определения какой конкретный DiscountCalculator отдать потребуются ещё зависимости придётся их инжектить както в сущность. посоветуйте пожалуйста как лучше сделать
Ну это же стандартная проблема Рич моделей. Что зависимости нужно передавать аргументами
Юра
Не знаю наверное есть. У нас нет рич моделей, у нас сервис слой
Юра
Ну был бы какой-то DiscountCalculator или менеджер
Вадим
типа фабрику, туда купон, оттуда получаешь калькулятор?
Юра
Скорее всего да какая-то фабрика которая возвращает нужную стратегию для купона
Вадим
Скорее всего да какая-то фабрика которая возвращает нужную стратегию для купона
я уже пробовал, там другая проблема. Я хотел чтобы клиентский код выглядел както так: public function calculatePrice(Product $product, Seller $seller, Coupon $coupon = null): Price { $price = $product->getPrice(); if (! is_null($coupon)) { $price->addCoupon($coupon); } return $price->applyTax($seller->getTax()); } если придумать фабрику то её тогда нужно будет передавать тоже: public function calculatePrice(Product $product, Seller $seller, Coupon $coupon = null): Price { $price = $product->getPrice(); if (! is_null($coupon)) { $price->addCoupon($coupon, $this->discountCalculatorFactory); } return $price->applyTax($seller->getTax()); }
Вадим
както некрасиво чтоли
Вадим
или тут получить калькулатор и передавать его
Вадим
хотя тип калькулятора зависит только от типа купона и логично его бы оттуда получить
Nikolay
class Price { public function calculateWithDiscount(int $tax, Coupon $coupon) { if ($coupon->type === CouponType::DiscountPercent) { .... } ... } }