【问题标题】:Configuration and inheritance chains in PHPPHP 中的配置和继承链
【发布时间】:2013-09-18 15:47:10
【问题描述】:

我有几个标准类:

abstract class Parent {}
class Child1 extends Parent {}
class Child2 extends Parent {}

Parent 类包含两个子类共有的逻辑,但每个子类都有自己的附加逻辑。

对于我的每个客户,此逻辑都可以配置。所以对于任何特定的客户,我可能有:

abstract class ClientParent {}
class ClientChild1 extends ClientParent {}
class ClientChild2 extends ClientParent {}

我遇到的问题是如何将标准类中的逻辑放入这些类中。第一种方法是这样的:

abstract class ClientParent extends Parent {}

好的,现在我的所有客户端特定类中都有标准父逻辑。伟大的。但是子类已经在扩展ClientParent,所以我们不能为它们做同样的事情。我的“解决方案”就是这样做:

abstract class Parent {}
class Child1 extends ClientParent {}
class Child2 extends ClientParent {}

abstract class ClientParent extends Parent {}
class ClientChild1 extends Child1 {}
class ClientChild2 extends Child2 {}

那里;现在所有适当的逻辑都被传递下来,每个人都很高兴。除了现在我的标准类耦合到特定的客户端。由于我有很多客户,这显然不好。

我在这里有什么?有没有办法单独通过继承来解决这个问题,还是我应该研究更复杂的配置注入策略?

编辑:

我使用的是 PHP 5.3,所以我无法使用traits 来解决这个问题。

【问题讨论】:

    标签: php oop inheritance configuration


    【解决方案1】:

    PHP 不支持多重继承,我认为这是您在此处尝试的近似值。但是它确实支持(从 5.4 开始)traits,在许多情况下它可以为您提供类似的功能。

    trait ParentTrait {
       public function someUsefulMethod(){/*...*/};
       public function someOtherUsefulMethod(){/*...*/};
    }
    
    abstract class ClientParent(){}
    
    class ClientChild1 extends ClientParent {
          use ParentTrait;
    }
    
    $clientChild1 = new ClientChild1();
    $clientChild1->someUsefulMethod();
    

    另一种选择是使用组合代替,可能对于您的问题,使用策略模式会起作用。

    class SuperWidget extends Widget{
        private $dataStrategy;
    
        public function __construct(DataStrategy $strategy){
             $this->dataStrategy = $strategy;
        }
    
        // do this if you need to expose the functionality. 
        public function getData(){
            return $this->dataStrategy->getData();
        }
    
        // or if you are just using it in your class
        public function renderWidget($option){
            $data = $this->dataStrategy->getData($option);
            // use the data to render the widget;
            return $renderedWidget;
        }
    }
    
    $dataStrategy = JsonDataStrategy("http://data.source.url/jsonService.php");
    $widget = new SuperWidget($dataStrategy);
    

    【讨论】:

    • 不幸的是,我无法使用特征(我会将此添加到我的问题中)。它本身并不是真正的多重继承。我真的只是想弄清楚如何以 DRY 方式传播配置。显然,我最初尝试使用继承来做到这一点,但我对任何事情都持开放态度。
    • 我给了 +1,因为这个答案肯定会帮助那些使用 PHP 5.4+ 有类似问题的人。
    • @drrcknisn 您的 ClientChild1 类的实例和 Parent 类的实例之间的关系是什么。我相信有一种使用组合的方法,但是示例代码中类名的抽象程度使得很难确定组合对象的最佳方式是什么。在您的情况下,“a ClientClass1 是 Parent”的说法是否有意义,或者“ClientClass1 需要父母”是否更有意义。
    • "ClientChild1 is a Parent" 是有道理的,但由于所有这些类都只是小部件的容器(其中一些需要继承),它们没有必须位于同一继承树中。我认为构图可能会奏效,但如果我这样做,我还没有想好如何让它保持干燥。
    • 只需将应该共享的功能包装在不同的对象中并将其传递给对象...我将在答案中添加一个示例。
    猜你喜欢
    • 2013-08-14
    • 2012-10-05
    • 2011-12-20
    • 1970-01-01
    • 2021-11-01
    • 2011-02-14
    • 1970-01-01
    • 2018-02-09
    • 1970-01-01
    相关资源
    最近更新 更多