Php 此场景的构造函数替代方案
我有一个类,它包含一个私有属性,在许多类和方法中使用:Php 此场景的构造函数替代方案,php,oop,design-patterns,Php,Oop,Design Patterns,我有一个类,它包含一个私有属性,在许多类和方法中使用: class MyClass { private $_myProperty; public function __construct($myPropertyId) { $this->_initMyPropertyModel($myPropertyId); } public function initMyPropertyModel() { $this-&
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.如果未正确实例化,则从构造函数中抛出异常,但我认为这一点都不可取。在您描述的这个场景中,我将使用依赖项注入(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
如果两个属性对象具有相同的方法,这并不重要
如果它们没有实现相同的接口。通过这种方式,您可以强制客户机按预期的方式使用MyClass
,而不必担心传递对象无法使用的错误参数
当然,由使用您的类的客户端来正确检查对象,以避免出现错误:
$prop2 = new MyProperty2();
if ($prop2 instanceof MyPropertyInterface) {
$myObj2 = new MyClass(new MyProperty2());
} else {
// throw exception, show error, w/e
}