2013-08-27 50 views
1

我有一个包含了在大量的类方法使用的私有财产类:构造替代对于这种情况

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

的consructor需要一个模型的ID,然后试图实例模型从那个ID。该模型被设置为属性,然后用于所有其他类方法。

这样做的问题是,该模型instatiation可能出错,并因此在每个使用它的方法,一个潜在的问题模式不正确实例。

有没有更好的方式来处理这个代码?另外两种选择我看到的是:1。 强制客户端通过创建的模型,而不是ID 2.具有在使用模型 3.遥,从构造异常每个方法的空支票的,如果不妥善实例化但我不认为这是完全适合的。

回答

1

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

使用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 

它并不真正重要,如果这两个属性的对象具有相同的metods ,如果他们不执行相同的接口。您正在迫使客户通过这种方式使用MyClass预计使用,再也不用担心错传递参数,你的对象不能与工作方式。

当然,它是由客户使用你的类正确检查对象,所以没有出现错误:

$prop2 = new MyProperty2(); 
if ($prop2 instanceof MyPropertyInterface) { 
    $myObj2 = new MyClass(new MyProperty2()); 
} else { 
    // throw exception, show error, w/e 
}