Ответы пользователя по тегу ООП
  • В чем преимущество "фабричного метода" перед простым созданием объектов?

    myks92
    @myks92 Куратор тега PHP
    Нашёл решение — пометь вопрос ответом!
    Фабричный метод — это порождающий паттерн проектирования, который определяет общий интерфейс для создания объектов в суперклассе, позволяя подклассам изменять тип создаваемых объектов.

    В PHP, в отличии от других некоторых языков конструктор один. Из-за чего объект нельзя создать несколькими способами, с другими бизнес правилами. Поэтому принято конструктор делать приватным, а объект создавать через фабричные методы вроде create(), requestJoinByEmail(), joinByNetwork() и другие.

    Возьмём всем известных User-ов, которые могут появиться в нашей системе по-разному:

    1. Создание пользователя Администратором через метод create().
    2. Регистрацией пользователя по Email через метод requestJoinByEmail().
    3. Регистрацией пользователя через социальную сеть через метод joinByNetwork().

    Таким образом наш объект становится более гибким и содержит в себе разные бизнес требования к состоянию в зависимости от способа его создания.

    Чтобы хорошо понять суть рекомендую прочитать полезный ресурс — Refactoring Guru - Фабричный метод.
    Ответ написан
    3 комментария
  • Чем плохо использование статических функций в проекте для архитектуры?

    myks92
    @myks92
    Нашёл решение — пометь вопрос ответом!
    Вообще использование статистических функций это не плохо, если Вы понимаете их назначение и используете их правильно в простых вещах вроде Helper. Но не нужно превращать весь проект в статистическую бестию.

    Объекты инкапсулируют состояние и поведение, а статистическая функция лишина этого.

    Что сказано в документации PHP о статических функциях:

    Объявление свойств и методов класса статическими позволяет обращаться к ним без создания экземпляра класса. К ним также можно получить доступ статически в созданном экземпляре объекта класса.

    Так как статические методы вызываются без создания экземпляра класса, то псевдопеременная $this недоступна внутри статических методов. Поэтому важная причина, по которой Вам стоит избегать статических методов, заключается в том, что их использование теряет одно из преимуществ объектов. Объекты предназначены для инкапсуляции данных. Это предотвращает появление неожиданных побочных эффектов, которые позволяют избежать ошибок, улучшает тестирование. Статические методы не имеют инкапсулированных данных и поэтому не получают этого преимущества.

    Так же статические методы всегда создают экземпляр объекта при загрузке приложения, независимо от того будете ли Вы использовать этот объект или нет. Это увеличивает нагрузку на память.

    Что касаемо именно выборки из базы, то тут как минимум будет зависимость на одном хранилище. Что если вы сейчас хотите забирать данные из Mysql, а завтра из PosgreSQL. В вашем случае будет очень сложно перейти от одного хранилища к другому, но если бы вы использовали объект Repository, то вы бы просто написали новую реализацию и заменили бы через DI контейнер.
    Ответ написан
    1 комментарий
  • Переход к PHP-фреймворку. Какому?

    myks92
    @myks92 Куратор тега PHP
    Нашёл решение — пометь вопрос ответом!
    Порядок:
    1. Yii2
    2. Laravel
    3. Symfony

    Yii2 слишком старый, но очень хорош для старта. Можно подождать Yii3, либо сразу начинать с Symfony. Это вам обеспечит много сложностей, но при этом даст хорошее будущее. Так как в хороших компаниях практически все используют Symfony. Если покажется сложным и не подъёмным - вернитесь к Yii2.

    Рекомендую к прочтению:
    Ответ написан
    2 комментария
  • Как лучше сделать с ООП?

    myks92
    @myks92 Куратор тега PHP
    Нашёл решение — пометь вопрос ответом!
    Не очень понятна ваша реализация. В зависимости от задачи можно использовать так и так.
    Так же можно прибегнуть с использованием DI контейнеров, а вопрос создания нескольких сессий можно решить фабричным методом или возвращением клона объекта.
    Ответ написан
    Комментировать
  • Как абстрагировать аргумент конструктора при таком подходе?

    myks92
    @myks92 Куратор тега PHP
    Нашёл решение — пометь вопрос ответом!
    Я, конечно, слабо знаком с Laravel, но наследование мне не очень нравится. Лучше использовать DI. Поэтому, чтобы не наследоваться от классов фреймворка - просто не наследуйтесь от них) Вот так просто) Создайте свои классы и уже к ним подключите Laravel. Тогда и фреймворконезависимость увеличится. А реализацию настраивайте через DI. У адаптеров может быть метод support, который проверяет поддержку адаптера.
    Ответ написан
    4 комментария
  • Является ли это исключительной ситуацией?

    myks92
    @myks92 Куратор тега PHP
    Нашёл решение — пометь вопрос ответом!
    В сущность должны передаваться конкретные параметры: $id, $login, а не массив $userData, из которого потребуется извлекать эти данные, проверять их тип и существование. При таком подходе вы можете использовать типизацию и будете уверены в переданных данных.

    Вы так же можете создавать сущность разными фабричными методами.

    Исключение должно быть в методе get() вашего репозитория. И не путайте методы find() и get():

    • find() — возвращает сущность или null.
    • get() — возвращает сущность или исключение.
    Ответ написан
    Комментировать
  • Какие сущности или слои должно иметь приложения такого формата?

    myks92
    @myks92
    Нашёл решение — пометь вопрос ответом!
    1. DDD начинается не с базы, а с кода.
    2. Entity может быть разной. Если вы говорите про анемичную сущность, то у неё есть set и get. Однако это считается не очень хорошая практика. Больше она подходит для быстрой разработки. Поэтому сущность должна быть богатой. В идеале состоять только из методов модификации убирая get и set. В таком случае вы можете закладывать бизнес правила прямо в сущности. Вы сказали, что она не может состоять из логики - это ошибочно. Хорошая сущность должна иметь логику. Пример
    3. Entity ничего не возвращает. Это задача репозитория.
    4. Кроме Entity есть агрегат. Вот он как раз включает в себя все детали.

    Про DDD лучше читать или смотреть. Так как это достаточно обширная тема, в которой нужно разбираться не только по ответам на тостере, но и на практике.

    Статья в помощь: https://m.habr.com/ru/post/61524/
    Ответ написан
    Комментировать
  • Правильно ли я нарисовал план ООП игры шашки?

    myks92
    @myks92
    Нашёл решение — пометь вопрос ответом!
    В целом не плохо. Но бы сделал по другому.

    1. Свойства не выносить отдельно в схеме. Не совсем понятно что вы изменяете в методах. Какие условия при изменении. Какие параметры. И т. д. Свойства нужны больше для проектирования БД.

    Например лучше так:
    Подвесить клетку
    - цвет (string(6))

    2. Шашка это неотъемлемая часть доски. Поэтому модификация шашек будет из сущности доски.

    Для примера можете посмотреть как строится любое API. Везде есть метотоды и описание что они делают. Какие параметры принимают. Какой результат возвращают. Какого типа и так далее. Зайдите VK API сразу поймёте. Вам нужно сделать некое подобие API.

    В остальном нормально)
    Ответ написан
    2 комментария
  • Сколько строк нормально для класса?

    myks92
    @myks92
    Нашёл решение — пометь вопрос ответом!
    Где-то читал, что примерно 500-1000 строк для бизнес логики.

    Но:
    1. Количество строк никак не может зависеть от качества кода. У вас может быть 500 строк плохого кода, который не разберёт даже автор. Но если у вас код хотя бы по DDD, то с таким кодом жить проще. А если ещё есть тесты, то вдвойне лучше.

    2. У вас код может быть и на 1500 строк из-за подробной документации кода. Или же много строк получается из-за большого количества передаваемых параметров в методах. И такой метод приходится переносить - каждый параметр 1 строка. Пример.
    3. Не стоит ориентироваться на количество строк. Если код поддерживать и читать не сложно, то не заворачивайтесь. Если сложно - рефакторинг.

    А вообще советую писать код так, чтобы его можно было читать, как английский текст. Подбирать название переменных, методов, классов интерфейсов и т.д.
    Ответ написан
    Комментировать
  • Принцип DIP из SOLID и Autowiring из DI-контейнеров?

    myks92
    @myks92 Куратор тега PHP
    Нашёл решение — пометь вопрос ответом!
    Как это не будет? Может быть вы не правильно используете или не знаете как использовать?

    В DI контейнере мы «привязываем» класс, который реализует интерфейс. Таким образом везде, где есть этот интерфейс будет работать созданный и «привязанный» нами класс.

    Вроде бы там достаточно просто и понятно.
    Ответ написан
    9 комментариев
  • Набросал структуру классов учебного сайта доски объявлений, как еще лучше распределить функционал?

    myks92
    @myks92 Куратор тега PHP
    Нашёл решение — пометь вопрос ответом!
    Смотрите дальше курсы Елисеева. У него есть урок по проекту менеджеров. Где он разбивает все по паттерну CQRS. Вот ссылка на доменный слой https://github.com/ElisDN/demo-project-manager/tre...

    У вас получается, что UserService это Handler или UserHandler, если вы держите это все в одной папке. Посмотрите структуру. Я сейчас так же делаю и это очень просто понять. В UseCase папки то, что нужно делать:
    UseCase/User/Create
    В ней Файлы:
    Command.php
    Handler.php
    Form.php

    Или так:
    UseCase/User
    В ней Файлы:
    UserCreateCommand.php
    UserHandler.php
    UserCreateForm.php

    Если касаемо вашего, то не нужно повторять название методов в классе. UseServise метод просто login, а не userLogin

    Так же по названиям немного надо получше подумать. UserLoginOrLogoutServise удобнее назвать AuthServise...

    Не понятно откуда столько методов с началом в названии display

    Внедряйте репозиторий.
    Ответ написан
  • Написал класс но он выглядит как обычная функция, это нормально?

    myks92
    @myks92
    Нашёл решение — пометь вопрос ответом!
    Отдельные классы это хорошая практика. Однако, саму проверку стоит размещать там, где она используется. В вашем случае это сделано не совсем а равильно. Проверку нужно поместить в класс, объявления, но при этом ссылаться на проверку класса промо.

    Будет примерно так:
    public function getPromotion(): ?Promotion
    {
         return new Promotion($this->promotion_id, $this->promotion_time);
    }


    Далее помещаем метод проверки:
    public function isPromoted(): bool
    {
         return $this—>getPromotion()->isPromoted()
    }


    Если у вас данные для метода могут быть пустыми, тогда условие может выглядеть так
    public function isPromoted(): bool
    {
         return $this->getPromotion() ? $this—>getPromotion()->isPromoted() : false
    }


    Не претендую ни на что) Я делаю так) Создавать дополнительные классы это хорошо. Можно даже создать отдельный класс для Id. В типизации будет удобно работать. И понятно всем. Да и в целом не будет все в одном классе.
    Ответ написан
  • Как правильно реализовать реализовать классы Родитель->Потомок?

    myks92
    @myks92 Куратор тега PHP
    Нашёл решение — пометь вопрос ответом!
    Паттерн диспетчер событий.

    https://github.com/ElisDN/yii2-demo-shop/blob/mast...

    Там где нужно вызвать https://github.com/ElisDN/yii2-demo-shop/blob/mast...
    Обработчик https://github.com/ElisDN/yii2-demo-shop/blob/mast...

    Зависимости через DI
    https://github.com/ElisDN/yii2-demo-shop/blob/mast...
    Ответ написан
    Комментировать
  • Правильно я понял паттерн Command?

    myks92
    @myks92
    Нашёл решение — пометь вопрос ответом!
    Основное нужно понять, что Есть два класса:
    1. Команда
    2. Обработчик.

    Команда передается в обработчик и уже в обработчике вызывается метод "обработай". Чтобы более детально понять как это работает на практике и для чего это нужно предлагаю почитать о CQRS

    https://blog.byndyu.ru/2014/05/blog-post.html
    https://blog.byndyu.ru/2014/07/command-and-query-r...

    И пример как это сделано на PHP
    Ответ написан
    Комментировать