简体   繁体   English

根据PHP中的对象类型实例化不同的类

[英]instantiate different class based on the object type in PHP

I am searching for a architectural solution in instantiating different child classes based on an object type or extending Base class with the methods of child classes. 我正在寻找一种基于对象类型实例化不同子类或使用子类方法扩展基类的体系结构解决方案。

To give an example: There is a base class User and several child classes Partner , Client , Moderator which have specific methods an their own constructors. 举个例子:有一个基类User和几个子类PartnerClientModerator ,它们具有特定的方法和自己的构造函数。 When I am calling 当我打电话时

$user = new User($userid);

I want User class 我要用户课程

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
    }
  }
}

To return me an object with all of the methods depending on what roles does user have. 为了给我一个具有所有方法的对象,具体取决于用户的角色。

I know my logic is broken somewhere and the example I provided is wrong. 我知道我的逻辑在某处被破坏了,而我提供的示例是错误的。 But the only solution I see now is to build one giant class that has all of the methods for all of the roles - which looks like a mess. 但是我现在看到的唯一解决方案是建立一个巨型类,该类具有用于所有角色的所有方法-看起来很烂。

First of all, your database logic should be totally separate from your domain objects (User, etc). 首先,您的数据库逻辑应与域对象(用户等)完全分开。 Otherwise you are violating the single responsibility principle (SRP). 否则,您将违反单一责任原则(SRP)。

Set up your classes something like the following (base class User and multiple subclasses): 设置您的类,如下所示(基类User和多个子类):

class User 
{
  private $id;
  // getters and setters go here
}

class Moderator extends User {}
class Partner extends User {}
// etc

Then, create some sort of UserManager class that implements an interface that looks like the following: 然后,创建某种UserManager类,该类实现如下所示的接口:

interface UserManagerInterface {
  function loadUserById($id);
}

The implementation of that method should load the passed user id's information from the database, look at what type it is (partner, moderator, etc) and then instantiate the appropriate class and hydrate the appropriate information. 该方法的实现应从数据库加载传递的用户ID信息,查看其类型(伙伴,主持人等),然后实例化适当的类并合并适当的信息。

The problem is that you cannot call new User and get anything other than a User object. 问题是您不能调用new User并获得User对象以外的任何东西。

This sounds like the perfect use-case for the factory pattern. 这听起来像是工厂模式的完美用例。

The simplest form of this uses a static method to invoke the correct constructor. 最简单的形式是使用静态方法来调用正确的构造函数。

So you could have code like this: 因此,您可以拥有如下代码:

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);
        }
    }
}

You can then call User::create($userid) to get the appropriate object. 然后,您可以调用User::create($userid)来获取适当的对象。

If your code is appropriately structured, it may well be possible to have code along the lines of Lusitanian's answer (fleshed out) that would do a better, more flexible job. 如果您的代码结构合理,则很有可能按照Lusitanian的回答(完善)的思路编写代码,这将做得更好,更灵活。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM