基于PHP中的对象类型实例化不同的类

时间:2013-01-15 00:39:09

标签: php

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

举个例子: 有一个基类用户和几个子类合作伙伴客户端主持人,它们有自己的特定方法构造函数。 当我打电话时

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

根据用户的角色,使用所有方法返回一个对象。

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

2 个答案:

答案 0 :(得分: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的信息,查看它的类型(伙伴,主持人等),然后实例化相应的类并保存适当的信息。

答案 1 :(得分: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的答案(充实),可以做更好,更灵活的工作。