使用 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);

先回答标题中的宽泛问题("What's the point of setters?"):

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

从代码中回答问题("Why add a setFoo($foo) method in addition to/instead of just __construct($foo)?"):

这取决于您要创建哪种 object。拥有 immutable objects 是绝对合理的,它们在实例化时获取一次数据,然后就无法修改该值。拥有一个 object 也是绝对合理的,您可以在其实例化后随时对其设置值。这两种情况在不同情况下都有用。

您甚至可以同时进行这两项操作。要求构造函数的参数可确保您的 object 始终始终具有特定值。然后,您还可以允许通过 setter 修改此值。两者一起使用可确保您的 object 始终处于 有效状态 ;也就是说,如果 object 没有特定值,就不能拥有它的实例。例如:

class Foo {

    protected $bar;

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

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

}

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