将四个类中的任意一个注入到一个类中


Inject any of four classes into a class

我有一个类(让我们称之为TestClassA),其中的构造函数看起来像这个

public function __constructor(SomeInterface $some, AnotherInterface $another, $additionalArgs = null)
{
    // Rest of code
}

$additionalArgs的值可以来自四个唯一类中的任何一个。这些类中的每一个都将根据用户的条件集向上面的类添加唯一的查询参数。让我们将这些类命名为

  • 测试B

  • TestC

  • TestD

  • 测试

我不确定接口注入是否是我的最佳解决方案,因为一旦设置了一个条件,它很可能再也不会改变,而且在任何给定的时间只能设置一个选项。例如,如果用户决定使用TestC类,那么他将更改为其他三个剩余类中的任何一个的概率几乎为零。因此,如果我是正确的,如果我使用接口注入(如下面的例子)并添加所有四个类,我将不必要地实例化3个类,因为它们很可能永远不会被使用

public function __constructor(
    SomeInterface $some, 
    AnotherInterface $another,
    TestBInterface $testB,
    TestCInterface $testC,
    TestDInterface $testD,
    TestEInterface $testE
) {
    // Rest of code
}

我想到的是创建一个属性为$additionalArgsTestClassA,创建一个所需类的新实例,比如TestC,然后将其传递给$additionalArgs,然后我在一个方法中使用它来获得所需的值。

示例

$a = new SomeClass;
$b = new AnotherClass;
$c = new TestC;
$d = new TestClassA($a, $b, $c->someMethod());

我的问题是,如何确保传递给$additionalArgs的值是应该传递给该参数的四个类之一的有效实例。我已经尝试在我的方法中使用instanceof来验证这一点,在本例中为someMethod(),但条件未通过

关于如何解决这个问题,并且仍然"遵守"OOP的基本原则,有什么建议吗?

当前您正在传递一个方法的结果,您无法测试它来自哪个类,因此instanceof无法工作。您需要做的是传入对象,测试它,然后调用该方法。试试这个:

class TestClassA() {
    $foo;
    $bar;
    $testB;
    $testC;
    $testD;
    $testE;
    public function __constructor(Foo $foo, Bar $bar, $test = null)
    {
        $this->foo = $foo;
        $this->bar = $bar;
        if ( ! is_null($test))
        {
            if ($test instanceof TestClassB)
            {
                $this->testB = $test->someMethod();
            }
            elseif ($test instanceof TestClassC)
            {
                $this->testC = $test->someMethod();
            }
            elseif ($test instanceof TestClassD)
            {
                $this->testD = $test->someMethod();
            }
            elseif ($test instanceof TestClassE)
            {
                $this->testE = $test->someMethod();
            }
            // Optional else to cover an invalid value in $test
            else
            {
                throw new Exception('Invalid value in $test');
            }
        }
        // Rest of code
    }
}
$a = new Foo;
$b = new Bar;
$c = new TestClassC;
$d = new TestClassA($a, $b, $c);