使用setter而不是通过构造函数传递参数的重点是什么?

时间:2015-01-20 11:50:29

标签: php scope encapsulation

为什么在将属性设置为私有时可以简单地将数据传递给构造函数的人会使用setter?

示例:

class recover_password{
    private $password;

    function __construct($password){
        $this->password  = $password;
        $this->show_pass();
    }

    function show_pass(){
        echo $this->password;
    }       
}

class recover_password{
    private $password;

    function set_pass($password){
        $this->password  = $password;
        $this->show_pass();
    }

    function show_pass(){
        echo $this->password;
    }       
}

//First object
$rec_pass = new recover_password(12345);

//Second object
$rec_pass = new recover_password();
$rec_pass->set_pass(12345);

1 个答案:

答案 0 :(得分:2)

首先回答标题中的广泛问题("重要的是什么?"):

使用setters 作为直接允许访问属性$obj->prop = 'foo')以更多地控制允许在对象上设置哪种属性以及何时可以组。 setter,一个函数,可以修改或彻底拒绝您尝试设置的值;通过简单的属性赋值,这是不可能的。

要回答代码中的问题("为什么要添加setFoo($foo)方法,而不仅仅是__construct($foo)?"):

这取决于您要创建的对象类型。拥有不可变对象是绝对合理的,这些对象在实例化时会获取一次数据,然后无法修改该值。在实例化之后的任何时候都有一个可以设置值的对象也是绝对合理的。这两种情况在不同情况下都很有用。

你甚至可以同时做两件事。要求构造函数的参数确保您的对象始终始终具有特定值。然后,您还可以通过setter修改此值。同时使用它们可确保您的对象始终处于有效状态;即,如果没有特定值,您就无法拥有该对象的实例。 E.g:

class Foo {

    protected $bar;

    public function __construct(Bar $bar) {
        $this->bar = $bar;
    }

    public function setBar(Bar $bar) {
        $this->bar = $bar;
    }

}

保证此类始终具有有效类型$bar的值(Bar)。您可以根据需要修改该值,但无法设置无效值或没有值。抛弃构造函数意味着你可以在没有Bar的情况下实例化类,省略setter意味着在实例化后你无法修改它。