PHP программист

написал в блог:
Абстракции и как они текут
Как джуниор-разработчику найти работу (vc.ru)
Тестовые задания для джуниоров PHP

написал на Хабре:
Геттеры/сеттеры и проблема с инкапсуляцией в Symfo...
Контакты
Местоположение
Россия, Москва и Московская обл., Москва

Достижения

Все достижения (69)

Наибольший вклад в теги

Все теги (255)

Лучшие ответы пользователя

Все ответы (871)
  • Как выполнить несколько методов одним разом python?

    Maksclub
    @Maksclub
    maksfedorov.ru
    пара способов

    ЦЕПОЧКА ВЫЗОВОВ
    В коде вы привели пример, как хотели бы использовать: caller.hello().world()

    Если хотите, чтобы последний метод возвращал результат, то можно так:
    class Hello(object):
        def __init__(self):
             self.msg = 'Hello'
    
        def hello(self, world):
            self.msg = self.msg + ', ' + world
            return self
    
        def print(self):
            return self.msg
    
    caller = Hello()
    msg = caller.hello('niriter').print()
    print(msg) # Hello, niriter

    Такого рода код используется в разного рода билдерах, когда нужно настроить обьект разным способом по разным условиям (разного рода билдеры, в ОРМ запрос собрать и прочее)

    В вашей библиотеке по работе с html такой способ и используется (наряду со вторым) — вызываете разного рода методы, а возвращает все тот же обьект с разным состоянием и вы всегда можете вызвать новый метод (удалить элемент, добавить, все стереть) и по итогу вызвать получение своего нужного HTML

    ИНКАПСУЛЯЦИЯ

    class Hello(object):
        def __init__(self, msg='Friend'):
             self.msg = msg
    
        def print(self):
            init_msg = self.hello()
            return init_msg + ',  ' + self.msg
        
        def hello(self): # этот метод вызываем изнутри другого метода
            return str("Hello")
    
    caller1 = Hello()
    print(caller1.print()) # Hello, Friend
    
    caller2 = Hello('Maks')
    print(caller2.print()) # Hello, Maks


    Инкапсуляция из мира ООП, наружу предоставляет некий метод, и вызвав его — выполнится некоторое поведение и изменение состояния. Нужна для сокрытия всех деталей и нюансов и оставляет только удобное АПИ для работы.

    В вашей библиотеке по работе с html такой способ и используется (наряду с первым) — прячет сложные алгоритмы извлечения элементов, манипуляции с ними, отдавая назад только удобное АПИ с понятными названиями
    Ответ написан
  • Что делать, если нужно получить часть данных сущности?

    Maksclub
    @Maksclub Куратор тега PHP
    maksfedorov.ru
    Для отображения используйте DTO и доставайте их из репозитория. Для логики отображения негоже сущности из бизнес-слоя вытягивать.

    1 способ — заюзать Доктрину
    сразу не увидел, что вы без нее работаете

    Доктрина умеет создавать дтошки из коробки
    class PostDTO
    <?php
    
    namespace App\DTO;
    
    class PostDTO
    {
        /** @var string */
        private $name;
        
        /** @var string */
        private $description;
        
        /** @var string */
        private $text;
        
        public function __construct(string $name, string $description, string $text)
        {
            $this->name = $name;
            $this->description = $description;
            $this->text = $text;
        }
    
        public function getName()
        {
            return $this->name;
        }
    
        public function getDescription()
        {
            return $this->description;
        }
    
        public function getText()
        {
            return $this->text;
        }
    }

    И используя синтаксис NEW DQL создаем наши DTO :
    $query = $em->createQuery('SELECT NEW App\DTO\PostDTO(p.name, p.description, p.text) FROM App\Entity\Post p');
    $users = $query->getResult(); // array of PostDTO

    Источник: https://www.doctrine-project.org/projects/doctrine...

    2 способ — заюзать DBAL/PDO
    Сделать запросы через более низкую прослойку без ORM (например через Doctrine DBAL или PDO) и результат фетчить в те же самые PostDTO в репе
    Ответ написан
  • Как задавать дополнительные свойства сущностям в Doctrine ORM?

    Maksclub
    @Maksclub
    maksfedorov.ru
    Теперь я использую Doctrine ORM, у которой свойства должны быть закрытыми, а сеттеры/геттеры для таких вещей (которые в базу не заносятся, только контроллер и вид) не надо делать.

    Доктрине фиолетово на приватность/открытость ваших свойств, ровно как и на наличие методов для их
    записи/чтения, кроме того этого сеттеры/геттеры распространены (абсолютно везде), но все равно это признак плохого кода, писал об этом статью на Хабре: Геттеры/сеттеры и проблема с инкапсуляцией.
    А так Доктрина работает с объектами через рефлексию.

    Как выводить нужные в другом слое данные, которые нужны для отображения, а не для бизнес-логики — DTO,
    отвечал на днях: Что делать, если нужно получить часть данных сущности?

    Если хотите работать с полем сущности, но не хотите чтобы оно загружалось из/в БД, то просто не делайте для этого поля аннотацию (или не указывайте его в yml, если используейте его для маппинга):

    @Column
    Marks an annotated instance variable as "persistent". It has to be inside the instance variables PHP DocBlock comment. Any value hold inside this variable will be saved to and loaded from the database as part of the lifecycle of the instance variables entity-class.
    https://www.doctrine-project.org/projects/doctrine...


    Итого:
    Рекомендую или DTO или сервис (как указал BoShurik), который вернет ссылку, при том в этот сервис можно скормить роутер и создавать сылку не по названию сущности, а по названию роута — это облегчит потом смену сразу всех роутов одного типа, если не меняете название. А вообще и DTO и сервис нужны. В любом случае сущность знать о роутах ничего не должна, тем более этих роутов под одну сущность можеть быть куда больше, чем /blog/ и меняться это может довольно часто...
    Ответ написан
  • Чем представлена абстракция (принцип ООП) в Java?

    Maksclub
    @Maksclub
    maksfedorov.ru
    Абстракция — ключевое явление в ООП

    Сам класс — уже абстракция чего-то, когда я создаю класс Product, то это абстракция некоторых объектов моей системы, что их отличает от всего внутреннего мира системы уже как минимум названием (и потом интерфейсом и поведением, описанным в классе).

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

    Также мы можем абстрагировать некий функционал от привязки к конкретному типу. И создать функционал над абстрактным (обобщенным) типом — дженерики (параметрический полиморфзм).

    Наследование, инкапсуляция и полиморфизм — ключевые способы для создания абстракции.
    • Полимофризм — создаем или интерфейс или абстрактный класс, что очертит границы абстракции и уже в конкретных реализациях абстракцию "материализуем". Или создаем некий класс, который работает с любым типом, но строго указанным при создании объекта (параметрический полиморфизм)
    • Наследование — похожее поведение у ряда классов выносим в абстракцию (родительский класс, абстрактный класс)
    • Инкапсуляция — очищаем абстракцию, отдав наружу только публичный интерфйес (границы абстракции), все остальное (не относящиеся к нашей абстракции) прячем
    Ответ написан

Лучшие вопросы пользователя

Все вопросы (44)