PHP -混合对象注入&继承


PHP - Mixing object Injection & inheritance

这是以下答案的后续问题:

class A {
    protected function doSomeStuff(){
       echo 'a method that all children will need to call';
    }
}
class B {
    protected $_parent;
    public function __construct($parent) {
       $this->_parent = $parent;
    }
    public function doSomeLocalStuff() {
       $this->_parent->doSomeStuff(); // Fatal Error
    }
}
$a = new A(); // will be used for other children as well.
$b = new B($a);
$b->doSomeLocalStuff();
在上面的代码中,使用了父对象注入,允许类B使用类a 的特定实例初始化,但是类B不能访问类a 受保护的属性或方法(例如,doSomeStuff())。

但是通过将上面的方法与继承相结合,我们得到了两全其美的效果:)

class B extends A {
    protected $_parent;
    public function __construct($parent) {
       $this->_parent = $parent;
    }
    public function doSomeLocalStuff() {
       $this->_parent->doSomeStuff(); // Works :)
    }
}

那么,这可以接受吗?.. 有没有缺点?

p。S:我正在尝试实现一个非静态工厂模式。

考虑这个,我试图设计一个类,将用于调用外部API。我们有超过400个不同的电话,分为10类(账单、客户、产品……).

所有的400个调用共享相同的父-url,用户名/密码和其他一些共同的属性。

所以,不是把400个方法放在一个大的类中,我决定把它们分成10个类,用一个父类处理常见的功能(例如,身份验证,url构造,web调用…),然后创建了一个工厂模式,我可以在运行时只加载需要的类/类别。

例如:

$apiCall = new parentPlusFactory(); 
          //contains common methods and a mechanism to load sub-classes
$apiCall->setAPIuserName("user");
$apiCall->setAPIpassword("pass");
$apiCall->useClass('customers')->doSomeCustomerStuff();
$apiCall->useClass('products')->doSomeProductStuff();

这就是为什么我需要共享同一个父类实例

与c++不同,PHP中没有friend关键字。您可以查看此讨论以了解实现friend类的方法。

但是您真的需要将该函数声明为protected吗?

一般来说,您应该倾向于组合而不是继承。对我来说,你的用例听起来像B根本不应该扩展A,但相反,你应该有两个独立的类。

现在,PHP 5.4将有"水平重用",也被称为"特征",它将有可能"包含"一个特征到你的类。

trait A
{
    public function doSomeStuff()
    {
        echo 'doing some stuff';
    }
}
class B
{
    use A;
    public function doSomeLocalStuff()
    {
        $this->doSomeStuff();
    }
}
class C
{
    use A;
    public function doSomeLocalStuff()
    {
        echo 'Doing something completely different here';
    }
}

参见PHP手册:traits和PHP 5.4 beta1发布