2013-01-15 86 views
2

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

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

$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

首先,你的数据库逻辑应该完全独立于你的域对象(用户等)。否则,你违反了单一责任原则(SRP)。

设置类类似如下(基类用户和多个子类):

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信息,查看它是什么类型(合作伙伴,主持人等),然后实例化适当的类并提供适当的信息。

+0

Lusitanian,谢谢你的回答! 所以我会怎样创建)的用户(或子女)的实例对象将被 1创建的UserManager类 2的实例)调用方法loadUserById它会返回一个正确的对象 看起来一样的方式工厂模式(通过拥有类userManager有一个静态方法)。但工厂模式看起来更短,更好。为什么更糟? –

+0

UserManager不会是静态类。它可以被实例化并且提供可扩展且易于单元测试的代码,并且也与单一责任原则(OOP)保持一致。 – Lusitanian

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的答案(充实完成)可能会做出更好,更灵活的工作。

+0

这并没有解决SRP违规问题,实际上也引入了静态工厂反模式。工厂是正确的路要走,但它应该在另一个类中确保可测试的固体代码。 – Lusitanian

+0

@Lusitanian我不认为你会从这一点开始承担单一的责任,说实话。当然,一个实例化的,灵活的,可测试的工厂往往是理想的,但并不总是可以实现的。我稍微编辑了我的答案;我希望它让你满意。 – lonesomeday

+0

呵呵,我想我的主要问题是他问了架构,并用oop标记了这一点,所以如果他刚开始他的应用程序指向他的方向是正确的,但我明白你来自哪里。 – Lusitanian

相关问题