繁体   English   中英

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

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

我正在寻找一种基于对象类型实例化不同子类或使用子类方法扩展基类的体系结构解决方案。

举个例子:有一个基类User和几个子类PartnerClientModerator ,它们具有特定的方法和自己的构造函数。 当我打电话时

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

为了给我一个具有所有方法的对象,具体取决于用户的角色。

我知道我的逻辑在某处被破坏了,而我提供的示例是错误的。 但是我现在看到的唯一解决方案是建立一个巨型类,该类具有用于所有角色的所有方法-看起来很烂。

首先,您的数据库逻辑应与域对象(用户等)完全分开。 否则,您将违反单一责任原则(SRP)。

设置您的类,如下所示(基类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);
}

该方法的实现应从数据库加载传递的用户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)来获取适当的对象。

如果您的代码结构合理,则很有可能按照Lusitanian的回答(完善)的思路编写代码,这将做得更好,更灵活。

暂无
暂无

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

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