Ответы пользователя по тегу ООП
  • Как грамотно реализовать одно соединение с базой данных на все приложение, с помощью Dependency Injection Container?

    @Vitsliputsli
    Создать зависимость можно только 2 способами, получив объект изнутри или проведя инъекцию снаружи. Если изнутри, то так или иначе понадобится синглтон, если снаружи, то ктото снаружи должен контролировать передачу одного и того же объекта во все нуждающиеся объекты.

    1. Изнутри. Очевидно просто инстанцировать объект - это очень плохой вариант. Более менее нормальный вариант, это сервис локатор, с методом возвращающим нужный объект работающим как синглтон (т.е. не нужен прям класс синглтона, только метод который проверяет существует ли объект). Выглядит это не очень, синглтон и сервис локатор не считают хорошим решением. Из минусов статичное обращение к сервис локатору создаст проблемы для подмены объекта. Для разных подключений вы можете создать отдельные методы сервис локатора или разрулить в одном методе динамический выбор. Реальная проблема - тестирование, вы не сможете мокировать объект работы с БД. Но, можно это сделать ухищрениями, сделав ленивое подключение, и метод подмены объекта БД, хотя придется этот метод тащить в каждый класс. Как вариант, делать инъекцию объекта сервис локатора. Но остается другой большой минус, сервис локатор "гвоздями прибит" к большинству классов и вам придется его везде таскать, т.е. о красивых компонентах без странной зависимости от сервис локатора можно забыть.
    2. Снаружи. Оптимально, и считается трендом - инъекция нужного объекта в конструктор. Будет ли это делать DIC или чтото иное не имеет значения. Не нужно таскать какието дополнительные сервис локаторы. Но данное решение имеет тот же минус, что и п.1, вы не сможете подменить объект на другой при мокировании:
    public function __construct(PDO $db)
    внедряемый объект обязан быть классом PDO, если хочется чтобы мок просто подсовывал одни и те же значения нужно менять на интерфейс, тогда моку достаточно выполнять требования интерфейса. Но, если ваш DIC использует автоматическое определение требуемых объектов по структуре конструктора, то использовать интерфейс не получится.
    Ответ написан
    Комментировать
  • Как поменять 2 функции в один класс?

    @Vitsliputsli
    ООП - это больше про объекты и их связи. Да, в какой-то степени боремся и с повторяемостью кода, но это не главное. Т.е. нужно смотреть на то, что это за объекты, если они родственные, то можно сделать абстрактный класс, но быть может больше подойдет инстанцирование в один класс разных объектов и вызов одноименной функции. А где-то вообще будет вызов динамический, а где-то быть может стоит и продублировать код. Все зависит от самих объектов и их связей.
    Ответ написан
    Комментировать
  • Как правильно сделать типизацию объектов?

    @Vitsliputsli
    Вы можете воспользоваться контравариантностью (php>=7.4), т.е. указать в абстрактном классе родительский класс для User:
    abstract protected function mapToArray(Model $object ): array;
    
    ...
    
    class User extends Model

    Либо ввести DTO, чтобы mapper брал данные из него и вообще никак не обращался к бизнесовым сущностям.
    Ответ написан
    6 комментариев
  • MVC (PHP): правильно ли понимаю слои?

    @Vitsliputsli
    Модель (Model) - слой работы с данными. мне сложно воспринять этот слой, т.к. вряд ли контроллер всегда работает напрямую с моделью ?

    Контроллер всегда напрямую работает с моделью.

    Наверняка же есть какие-то промежуточные слои ? Например Сервис ? А в сервисах уже вызываются DAO или Repository (кстати, в чем у них отличие?).

    Нет никаких промежуточных слоев. Какого рода логика будет в модели, это уже ваше право, MVC этим не занимается.
    Мысль MVC отделить обработку пользовательского ввода (Контроллер) и вывода (Представление) от внутренней логики приложения (Модель). Вот и все.

    Единственное, что можно отметить еще, в вебе принято, что контроллер передает данные в модель, забирает вывод и предает его в представление. В классическом mvc, контроллер передает данные в модель, а модель свой вывод передает напрямую в представление.
    Ответ написан
    Комментировать
  • Правильно ли я понимаю ООП?

    @Vitsliputsli
    ООП применимо в любой задаче, и да, в очень простых задачах оно может быть избыточно. Объекты ООП имеют мало отношения к реальному миру, это чисто техническая реализация, соответственно исходить нужно из технических требований в первую очередь, а не из биологической классификации видов.
    Из вопроса абсолютно не ясно, каковы требования. Вполне возможно что вам достаточно объектов учета, каждый объект это как строчка в книге учета. В зависимости от использования, возможно понадобятся объекты ресурсы даваемые объектами учета. Но все это зависит от предъявляемых требований.
    Ответ написан
    Комментировать
  • Как реализовать здачку в ООП?

    @Vitsliputsli
    Необходимо написать функцию которая принимает в качестве аргументов предполагаемый и реальный счёт, и возвращает целое число 0, 1 или 2 (нулевой, маленький или большой приз)

    Подскажите как сделать в ООП, как лучше сделать, саму суть.

    class Rewarding
    {
        const BIG_PRIZE = 2;
        const SMALL_PRIZE = 1;
        const ZERO_PRIZE = 0;
    
        private $bets;
        private $matches;
    
        public function __construct(BetsCollection $bets, Matches $matches)
        {
            $this->bets = $bets;
            $this->matches = $matches;
        }
    
        public function run() : void
        {
            /** @var Bet $bet */
            foreach ($this->bets as $bet) {
                /** @var Match $match */
                $match = $this->matches->getMatchById($bet->getMatchId());
                /** @var Score $score */
                $score = $match->getScore();
                $bet->setPrize($this->scoreBetCompare($bet->getScore(),$score));
            }
        }
    
        public function getBetsPrizes() : BetsCollection
        {
            return $this->bets;
        }
    
        private function scoreBetCompare(Score $betScore, Score $matchScore) : int
        {
            $bet1 = $betScore->getFirstCommandResult();
            $bet2 = $betScore->getSecondCommandResult();
            $match1 = $matchScore->getFirstCommandResult();
            $match2 = $matchScore->getSecondCommandResult();
            if ($bet1 === $match1 && $bet2 === $match2)
            {
                return self::BIG_PRIZE;
            }
            if (($bet1 > $bet2 && $match1 > $match2)
                ||
                ($bet1 < $bet2 && $match1 < $match2)
                ||
                ($bet1 === $bet2 && $match1 === $match2)
                )
            {
                return self::SMALL_PRIZE;
            }
            return self::ZERO_PRIZE;
        }
    }
    Ответ написан
    Комментировать
  • Можно ли это переписать на ООП? И как примерно всё это можно распределить по классам?

    @Vitsliputsli
    например вместо файла function_items.php будет Class Items и всё что в этом файле будет в одном классе, так?

    Нет, совсем не так, но для начала можете и так попробовать. Затем берите любой популярный фреймворк и пробуйте в нем, заодно изучай как реализует те или иные вещи фреймворк.
    Но это тогда, когда будете хорошо знать процедурный программирование.
    Ответ написан
    Комментировать