【发布时间】:2017-04-05 16:29:10
【问题描述】:
我正在阅读 an article 关于构造函数做太多工作的信息。 一段写着
在面向对象的风格中,依赖关系往往是倒置的,构造函数具有不同的且更加斯巴达式的角色。它唯一的工作是确保对象初始化到满足其基本不变量的状态(换句话说,它确保对象实例以有效状态开始,仅此而已)。
这是一个类的基本示例。在创建类时,我传入需要解析的 HTML,然后设置类属性。
OrderHtmlParser
{
protected $html;
protected $orderNumber;
public function __construct($html)
{
$this->html = $html;
}
public function parse()
{
$complexLogicResult = $this->doComplexLogic($this->html);
$this->orderNumber = $complexLogicResult;
}
public function getOrderNumber()
{
return $this->orderNumber;
}
protected function doComplexLogic($html)
{
// ...
return $complexLogicResult;
}
}
我正在使用它来调用它
$orderparser = new OrderHtmlParser($html);
$orderparser->parse()
$orderparser->getOrderNumber();
我使用parse 函数是因为我不希望构造函数执行任何逻辑,因为上述文章和this article 都表示这是一种糟糕的做法。
public function __construct($html)
{
$this->html = $html;
$this->parse(); // bad
}
但是,如果我不使用 parse 方法,那么我的所有属性(在此示例中仅为一个)将返回 null。
这是否称为处于“无效状态”的对象?
另外,有点感觉我的 parse 方法是变相的initialise 函数,另一篇文章也认为这很糟糕(尽管我不确定这是否仅在构造函数调用时该方法,当它被手动调用或两者兼而有之时)。无论如何,initialise 方法仍然在设置属性之前执行一些复杂的逻辑 - 这需要在 getter 被可靠地调用之前发生。
所以要么我误解了这些文章,要么这些文章让我认为我对这个简单类的整体实现可能是不正确的。
【问题讨论】:
-
考虑不将
$html传递给构造函数,而是传递给parse方法。然后其他方法的行为(返回 null)更有意义。您可以 仍然允许将参数传递给构造函数(可选),但是构造函数应该调用对象的 parse 方法。显然,可选行为不符合文章中表达的愿景,但我认为它可以接受。 -
谢谢你帮了我很多。
-
@myol - 我更新了我的回复,增加了对一般构造函数和构造函数异常的考虑。
标签: php oop design-patterns