什么';s使用setter而不是通过构造函数传递参数的意义


What's the point of using setters instead of passing arguments through the constructor?

当可以将数据简单地传递给构造函数,同时将属性设置为私有属性时,为什么要使用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);

首先回答标题中的广泛问题("setters的意义是什么?"(:

您使用setters来直接允许访问属性($obj->prop = 'foo'(,以便更好地控制允许在对象上设置什么类型的属性以及何时可以设置这些属性。setter,一个函数,可以修改或完全拒绝您试图设置的值;这在简单的属性分配中是不可能的。

要回答代码中的问题("为什么除了__construct($foo)之外还添加setFoo($foo)方法?"(:

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

你甚至可以同时做这两件事。构造函数需要一个参数可以确保您的对象始终具有特定的值。然后,您还可以允许通过setter修改此值。将两者结合使用可确保对象始终处于有效状态;也就是说,如果对象没有特定的值,就不可能有它的实例。例如:

class Foo {
    protected $bar;
    public function __construct(Bar $bar) {
        $this->bar = $bar;
    }
    public function setBar(Bar $bar) {
        $this->bar = $bar;
    }
}

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