【问题标题】:Instantiating a class in the constructor when the other class has instated the other class in the constructor当另一个类在构造函数中实例化另一个类时,在构造函数中实例化一个类
【发布时间】:2017-11-11 11:55:46
【问题描述】:

当我想在另一个类中使用一个类的方法和属性时,我会在构造函数中实例化这些类并将它们设置为实例属性。

<?php
class ClassA
{
    private $classB;
    private $classC;

    public function __construct()
    {
        // Instantiate class B and C and set the instance properties
        $this->classB = new ClassB();
        $this->classC = new ClassC();
    }

    // Example
    public function getTest() 
    {
        if ($this->classB->isTest1()) {
            return 'some value';

        } elseif ($this->classC->isTest1()) {
            return 'some other value';

        } else {
            return 'some other value';
        }
    }
}

$ClassA = new ClassA();
$test = $ClassA->getTest();

有时我想在构造函数中实例化一个类,而另一个类也实例化了另一个类的构造函数:

    <?php

    class ClassA
    {
        private $classB;

        public function __construct()
        {
            // Instantiate class B and set classB instance propert.
            $this->classB = new ClassB();
        }
    }

    class ClassB
    {
        private $classA;

        public function __construct()
        {
            // Instantiate class A and set classA property so we can use class A methods and properties in this class.
            $this->classA = new ClassA();
        }
    }

    $ClassA = new ClassA();
    $ClassB = new ClassB();

虽然这会失败,因为 A 类在构造函数中实例化 B 类,B 类在构造函数中实例化 A 类,并且它会不断重复执行此操作,直到我收到 PHP 错误消息“允许的内存大小为 ##” ### 字节耗尽'。

最好的解决方法是什么?任何帮助表示赞赏。

【问题讨论】:

  • 改用依赖注入。
  • 这看起来是个糟糕的设计,你在类结构中构建了如此多的依赖项,这注定会导致问题。
  • 除了@tereško 已经提到的dependency injection 的使用之外,这里的关键问题之一是您有一个cyclic dependency。这意味着你不能在没有B 的情况下实例化A,但你也不能在没有A 的情况下实例化B,这意味着你永远不能实例化任何一个类。

标签: php class oop constructor instantiation


【解决方案1】:

如果您的目标是在两个对象之间建立来回关系,那么众多解决方案之一就是在您拥有它时提供反向引用:

class ClassA {
    public $objB;

    public function __construct($other = null) {
        $this->objB = $other ? $other : new ClassB($this);
    }
}

class ClassB {
    public $objA;

    public function __construct($other = null) {
        $this->objA = $other ? $other : new ClassA($this);
    }
}

$objA = new ClassA();
var_dump($objA->objB->objA === $objA); // true

注意:我更喜欢将变量命名为 $objA 而不是 $classA,因为它们不是类,而是类的实例。

NB2:我将这些变量声明为公共成员,只是为了能够用var_dump 证明这些引用是有效的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    • 2022-01-21
    • 1970-01-01
    • 2019-12-06
    • 1970-01-01
    相关资源
    最近更新 更多