PHP - 混合对象注入和混合遗产

发布于 2024-12-07 14:10:07 字数 1785 浏览 0 评论 0原文

这是以下答案的后续问题:Parent Object in php

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();

上面的代码,使用了父对象注入,允许使用A类的特定实例来初始化B类,但是B类将无法访问A类受保护的属性或方法(例如,doSomeStuff())。

但是通过将上述内容与继承相结合,我们可以两全其美:)

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

那么,这是可以接受的吗? ..有什么缺点吗?

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

说明

考虑到这一点,我正在尝试设计一个用于调用外部 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();

这就是为什么我需要共享相同的父类实例。

This is a follow up question on the following answer : Parent Object in php

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();

In the above code, parent object Injection was used, allowing class B to be initialized using a specific instance of class A, but class B wont be able to access class A protected properties or methods (e.g., doSomeStuff()).

But by mixing the above with inheritance, we get the best of both worlds :)

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

So, is this acceptable ? .. any drawbacks ?

P.S: I'm trying to implement a non-static factory pattern.

Clarification

Consider this, I'm trying to design a class which will be used for calling an external API. We've over 400 different calls, divided into 10 categories (billing, customers, products ... ).

All the 400 calls shares the same parent-url, username/password and some other common properties.

So, instead of putting the 400 method in one big class, I decided to divide them into 10 classes, with a parent class handling common functions (e.g., authentication, url construction, web call ... ), then created a factory pattern, where I can load only needed classes/categories on run-time.

Something like :

$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();

That's why I need to share the same parent class instance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

原谅我要高飞 2024-12-14 14:10:07

PHP 中没有像 C++ 中那样的 friend 关键字。您可以查看此讨论以了解实现friend 课程。

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

There is no friend keyword in PHP, like in C++. You could check this discussion for a way to implement friend classes.

But do you really need that function to be declared protected?

一个人的旅程 2024-12-14 14:10:07

一般来说,你应该更喜欢组合而不是继承。对我来说,你的用例听起来像 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 手册:特征PHP 5.4 beta1 发布

In general you should favor composition over inheritance. To me your use case sounds like B should not be extending A at all, but instead you should have two separate classes.

Now, PHP 5.4 will have "horizontal reuse", also known as "traits", where it will be possible to "include" a trait into your class.

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';
    }
}

See also PHP manual: traits and PHP 5.4 beta1 released.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文