2

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

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

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

根据用户拥有的角色返回一个包含所有方法的对象。

我知道我的逻辑在某处被破坏了,我提供的示例是错误的。但我现在看到的唯一解决方案是构建一个包含所有角色的所有方法的巨型类——这看起来像一团糟。

4

2 回答 2

4

首先,您的数据库逻辑应该与您的域对象(用户等)完全分开。否则,您将违反单一责任原则 (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 信息,查看它是什么类型(合作伙伴、主持人等),然后实例化适当的类并混合适当的信息。

于 2013-01-15T00:47:33.860 回答
2

问题是您不能调用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 的答案(充实)的方式编写代码,这样可以做得更好、更灵活。

于 2013-01-15T00:47:11.117 回答