我有一个包含很多类方法中使用的私有属性的类:
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实例化模型。该模型被设置为属性,然后在所有其他类方法中使用。
这个问题是模型实例可能出错并且模型没有正确实例化,因此每个使用它的方法都存在潜在的问题。
有没有更好的方法来处理这段代码?我看到的另外两个选项是: 1.强制客户端传递创建的模型而不是id 2.在使用该模型的每个方法中检查null 3.如果没有正确实例化,则从构造函数中抛出异常,但我认为这根本不可取。
答案 0 :(得分:1)
在这种情况下,您将描述我将使用依赖注入(DI),因此代码可能更灵活,更易于管理和稳定。 基本上你的方法A B和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
如果两个属性对象具有相同的metod并不重要
如果他们不实现相同的界面。这样就迫使客户使用MyClass
预期使用的方式,从不担心传递对象无法使用的错误参数。
当然,由客户端使用您的类来正确检查对象,因此不会发生错误:
$prop2 = new MyProperty2();
if ($prop2 instanceof MyPropertyInterface) {
$myObj2 = new MyClass(new MyProperty2());
} else {
// throw exception, show error, w/e
}