0

我有一个包含私有属性的类,该属性在许多类方法中使用:

class MyClass
{
    private $_myProperty;

    public function __construct($myPropertyId)
    {
         $this->_initMyPropertyModel($myPropertyId);
    }

    public function initMyPropertyModel()
    {
        $this->_myProperty = new MyProperty($this->_myPropertyId);
    }

    public function methodA()
    {
        // do stuff with $this->_myProperty;
    }

    public function methodA()
    {
        // do stuff with $this->_myProperty;
    }

    public function methodC()
    {
        // do stuff with $this->_myProperty;
    }
}

构造函数获取模型的 id,然后尝试从该 id 实例化模型。该模型被设置为一个属性,然后在所有其他类方法中使用。

这样做的问题是模型实例化可能会出错并且模型没有正确实例化,因此使用它的每个方法都存在潜在问题。

有没有更好的方法来处理这段代码?我看到的另外两个选项是: 1. 强制客户端传递创建的模型而不是 id 2. 在每个使用模型的方法中检查 null 3. 如果没有正确实例化,则从构造函数中抛出异常,但我没有认为这是完全可取的。

4

1 回答 1

1

在您所描述的这种情况下,我将使用依赖注入 (DI),因此代码可能更加灵活、易于管理和稳定。
基本上,您的方法 AB 和 C 取决于正确的属性模型,因此应避免检查 null。
抛出异常总是一个不错的选择,因为它解释了做错了什么。

使用 DI 而不是通过构造函数和/或initMyPropertyModel()负责创建适当模型(紧密耦合)的方法来创建类,外部进程应该对此负责。您的构造函数应该只依赖于模型接口

class MyClass {
    // do not use private visibility unless you are sure it really needs to be private
    protected $_myProperty;

    // we dont care about the concrete object as long as it follows the required interface
    public function __construct(MyPropertyInterface $property) 
    {
        $this->_myProperty = $property;
        $this->_myProperty->initProperty(); // thanks to interface, MyClass can be sure this method can be called!
    }
    //... more class code
}

interface MyPropertyInterface
{
    public function initProperty();
}

class MyProperty implements MyPropertyInterface
{
    public function initProperty()
    {
        echo 'MyProperty initiated!';
    }
}
class MyProperty2
{
    public function initProperty()
    {
        echo 'MyProperty initiated!';
    }
}

使用示例:

$myObj = new MyClass(new MyProperty()); // works
$myObj2 = new MyClass(new MyProperty2()); // Catchable fatal error

如果两个属性对象没有实现相同的接口,它们是否具有相同的方法并不重要。通过这种方式,您将强制客户端使用MyClass预期使用的方式,而不必担心传递您的对象无法使用的错误参数。

当然,这取决于使用您的类的客户来正确检查对象,以免发生错误:

$prop2 = new MyProperty2();
if ($prop2 instanceof MyPropertyInterface) {
    $myObj2 = new MyClass(new MyProperty2());
} else {
    // throw exception, show error, w/e
}
于 2013-08-27T17:43:14.610 回答