PHP: Один объект может создаваться из многих других, где правильнее размещать фабрики ?

Начальная диспозиция: есть объекты типа Video, которые могут создаваться и инициализироваться с какой-то логикой объектами других типов News, Post, Episode - эти объекты не родственные между собой. Вопрос, как правильнее распределить фабрики между классами ?
Вариант 1:
Class News {
   public function createVideo()  {
       $video = new Video;
       $video->title = $this->title;
       $video->picture_id = $this->picture_id;
       $video->save();
 
       $link = new News_Video;
       $link->news_id = $this->id;
       $link->video_id = $video->id;
       $link->save();
 
       return $video;
  }
}
 
Class Post {
   public function createVideo()  {
      //
  }
}

Class Episode {
   public function createVideo()  {
      //
  }
}

$news = NewsStorage::find(1);
$video = $news->createVideo();

Вариант 2
Class Video {
   static public function createFromNews( News $news )  {
       $video = new self;
       $video->title = $news->title;
       $video->picture_id = $news->picture_id;
       $video->save();
 
       $link = new News_Video;
       $link->news_id = $news->id;
       $link->video_id = $news->id;
       $link->save();
 
       return $video;
  }

  static public function createFromPost( Post $post )  {
    //
  }

  static public function createFromEpisode( Episode $episode )  {
    //
  }
}
 
$news = NewsStorage::find(1);
$video = Video::createFromNews($news);

Самому мне кажется второй вариант более правильный, в силу того, что логика всех способов создания Video инкапсулирована в самом классе, с другой стороны первый вариант представляется более понятным с точки зрения человеческой логики.
  • Вопрос задан
  • 2523 просмотра
Пригласить эксперта
Ответы на вопрос 2
7workers
@7workers
Это чисто технический вопрос. Во втором варианте у вас метод не привязан к классу(ам). Во первом у вас есть обращение к $this, так что это уже ООП. С кодом из первого примера будет легче разобраться через год.
Ответ написан
Комментировать
@sashok1337
Насколько я понял, у Video есть некоторое кол-во полей, которые заполняются независимо от типа объекта (News, Post или Episode). Если это так - то достаточно только проследить за тем, чтоб классы имели одинаковые название полей(title, picture_id), необходимых для создания объекта типа Video. Это можно сделать, например, используя абстрактный класс либо интерфейс.
Выйдет примерно следующее:
Class News {
   public function createVideo($entity)  {
       $video = new Video;
       $video->title = $entity->title;
       $video->picture_id = $entity->picture_id;
       $video->save();
 
       $link = new News_Video;
       $link->news_id = $this->id;
       $link->video_id = $video->id;
       $link->save();
 
       return $video;
  }
}


Если же там какая-то кастомная логика для каждого класса - можно её в swich запихнуть.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы