• В чем нюанс php скрипта?

    PavelK
    @PavelK
    Добавьте проверку, действительно ли $v является массивом (php.net/manual/ru/function.is-array.php) перед запуском цикла.
    Ответ написан
  • Какой из этих подходов в ООП лучше и как они называются?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    с самого начала у нас есть более-менее абстрактный класс


    Так не должно быть. "абстрактные" классы это способ устранения дублирования, нам больше важны интерфейсы объектов и полиморфизм. Но конкретно в рассматриваемом примере нам важна только инкапсуляция.

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

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

    Если мы хотим создать объект с каким-то состоянием по умолчанию - мы берем первый вариант (либо как в примере прописывваем прямо как значение свойства, либо сэтим в конструкторе).

    Если мы хотим создать "пустой" объект и уже потом определить его состояние - мы выбираем второй вариант. Как правило этот способ создает много побочных эффектов если не контролировать его, да и обычно это делают не потому что так правильно а потому что подругому не умеют (типичный пример - сущности доктрины. Многие просто не представляю себе как с ними работать без сеттеров).

    Если же мы хотим создать объект но он не может быть пустым, объект должен требовать начальное значение в момент создания. Тогда мы просто передаем значение в конструктор. Без этого значения (или с неправильным) мы не сможем создать объект. К примеру если у пользователя обязательно должен быть email и пароль имеет смысл "заставлять" разработчиков явно передавать их в конструктор объекта. Это эдакая вариация.

    А теперь попробуем первый и второй подходы вместе + третий кейс с обязательными параметрами:

    class User {
         private $id;
         private $email;
         private $password;
    
         public function __construct($email, $password) 
         {
               // это ваш первый пример только без наследования, оно не нужно
               // в нашей задаче идентификатор пораждается
               // при создании объекта самим объектом, состояние по умолчанию
               $this->id = Uuid::uuid4(); 
    
               // мы требуем входящие данные что бы задать начальное состояние
               $this->email = $email;
               $this->password = $password;
         }
    
         // мутация состояния, второй вариант.
         public function changePassword($password) 
         {
                $this->password = $password;
         }
    }


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

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