создать экземпляр другого класса на основе типа объекта в PHP

Я ищу архитектурное решение для создания экземпляров различных дочерних классов на основе типа объекта или расширения базового класса с помощью методов дочерних классов.

Чтобы привести пример: существует базовый класс User и несколько дочерних классов Partner , Client , Moderator, которые имеют конкретные методы и свои собственные конструкторы. Когда я звоню

$user = new User($userid); 

Я хочу класс пользователя

 class User { public function __construct($userid) { self::initDB(); if ($this->isPartner()) { //extend this class with the methods of "Partner" child class and run "Partner" class constructor } if ($this->isClient()) { //extend this class with the methods of "Client" child class and run "Client" class constructor } if ($this->isModerator()) { //extend this class with the methods of "Moderator" child class and run "Moderator" class constructor } } } 

Чтобы вернуть мне объект со всеми методами в зависимости от того, какие роли у пользователя есть.

Я знаю, что моя логика сломана где-то, и пример, который я представил, ошибочен. Но единственным решением, которое я вижу сейчас, является создание одного гигантского класса, который имеет все методы для всех ролей, которые выглядят как беспорядок.

Related of "создать экземпляр другого класса на основе типа объекта в PHP"

Прежде всего, ваша логика базы данных должна быть полностью отделена от ваших объектов домена (Пользователь и т. Д.). В противном случае вы нарушаете принцип единой ответственности (СРП).

Настройте свои классы примерно следующим образом (базовый класс User и несколько подклассов):

 class User { private $id; // getters and setters go here } class Moderator extends User {} class Partner extends User {} // etc 

Затем создайте класс UserManager который реализует интерфейс, который выглядит следующим образом:

 interface UserManagerInterface { function loadUserById($id); } 

Реализация этого метода должна загружать переданную информацию идентификатора пользователя из базы данных, посмотреть, какой тип она (партнер, модератор и т. Д.), А затем создать экземпляр соответствующего класса и увлажнить соответствующую информацию.

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

Это звучит как идеальный вариант использования для заводской картины.

Простейшая форма этого метода использует статический метод для вызова правильного конструктора.

Таким образом, у вас может быть такой код:

 class User { public static function create($userid) { // get user from the database // set $isPartner to true or false // set $isClient to true or false // set $isModerator to true or false if ($isPartner) { return new Partner($userid); } elseif ($isClient) { return new Client($userid); } elseif ($isModerator) { return new Moderator($userid); } else { return new User($userid); } } } 

Затем вы можете вызвать User::create($userid) чтобы получить соответствующий объект.

Если ваш код надлежащим образом структурирован, вполне возможно иметь код в соответствии с ответом Лузитанана (fleshed out), который будет делать более гибкую работу.