我应该或不应该使用getter和setter方法吗?

Rea*_*ues 24 php oop getter-setter

好吧,这真的让我烦恼,我开始认为这一切都取决于个人选择,而不是提高效率或编写更好的代码的特定方式:我应该还是不应该在PHP项目中使用getter/setter方法?到目前为止,我读过的答案相当矛盾,并不完全适合PHP,这不是一种编译语言.例如,在Stack Overflow上讨论这个问题(" 为什么要使用getter和setter?").关于为什么我应该在我的代码中使用它们有很多很好的理由,但是所有的儿童评论都提到了访问者是如何邪恶的并且应该避免,在几个更令人不安的评论之间穿插,提到它们应该完全避免,因为它"搞砸你的代码".

我得到的只是相互矛盾的答案,其中没有一个与解释的PHP环境相关.有人可以阐明为什么/为什么不在PHP中使用它们,以及它们的决定背后的理由?如果我们可以简单地将属性定义为私有或受保护并且无论如何:

封装吸气剂和定型器提供的是可笑的薄

...引自"sbi"(为什么要使用吸气剂和二传手?)

就个人而言,我仍然不知道如何:

Class Foo {
    public $bar;

    function setBarType($val) {
       $this->bar = $val;
    }
}

$fee = new Foo();
$fee->setBarType(42);
Run Code Online (Sandbox Code Playgroud)

优于此:

Class Foo {
    public $bar;
}

$fee = new Foo();
$fee->bar = 42;
Run Code Online (Sandbox Code Playgroud)

Mik*_*ert 17

你链接的博客文章以一个重要的句子开头(强调添加):

代码中的每个getter和setter都表示无法封装并创建不必要的耦合.

封装是面向对象编程最重要的思想.它本质上归结为通过将它整齐地包装在类中来隐藏复杂性.在理想的世界中,当你使用一个类时,你不应该对它的内部运作或状态有任何了解.有些人(比如这个博客作者)会争辩说,拥有getter和setter已经是关于班级内部的太多信息了.在他们看来,一个类应该只有让我们能够告诉对象做某事的方法,从不介意它是如何做到的或它处于什么状态.使用setter不是"告诉对象做某事",它是从外面篡改对象的状态.

而不是这样做:

$a = myObject();

// Querying object state, making a decision outside the object, and changing its state
if ($a->getWarbleFizz() < 42) {
    $a->setYourWarbleFizzTo(42);
}

// Gee, I hope I made the right decision...
$a->nowDoSomethingUseful();
Run Code Online (Sandbox Code Playgroud)

你应该写这样的代码:

$a = myObject(42);
$a->doStuff();
Run Code Online (Sandbox Code Playgroud)

或这个 :

$a = myObject();
$a->doStuff(42);
Run Code Online (Sandbox Code Playgroud)

相关阅读:告诉,不要问.


Jua*_*des 13

因为如果设置值的实现如何更改(到数据库),则不必更改调用者.另一个例子是您可能需要在设置之前对值进行一些检查.

有一个方法可以让你拦截该变量的设置/获取,当它看起来不像你需要它时,它会让你的代码变得更友好.

物业吸气剂

像C#和最新版本的JavaScript这样的语言允许您拦截属性读取和写入,因此您可以使用支持它的语言中的属性.

对象观察者

有些语言允许您拦截所有JavaScript的Object.watch的读取/设置,或使用PHP的__get拦截不可访问的属性.这允许您实现getter和setter,但是由于他们为每个属性访问创建的开销,您会受到性能影响.这个答案谈到了getter和setter的其他问题.最佳实践:PHP Magic Methods __set和__get

Getters和Setters都可以,但......

制作样板吸气剂和制定者更好,但几乎和公共财产一样糟糕.如果任何人可以更改对象的状态(特别是具有多个属性),则它将无法很好地封装. http://cspray.github.io/2012/05/13/stop-calling-them-getters-setters.html


小智 8

使用getter和setter的巨大好处是,无论何时需要进行更改,您只需要修改getter和setter.

我将尝试用一个例子来解释:

protected $date;
public function getDate(){
    return $this->date;
}
public function setDate($date){
    $this->date = $date;
}
Run Code Online (Sandbox Code Playgroud)

想象一下,有一个原因,日期总是应该增加一天.您必须在您访问类成员的整个项目中进行搜索.

但是通过使用getter和setter,您可以将代码更改为:

protected $date;
public function getDate(){
    return $this->date;
}
public function setDate($date){
    $date = new DateTime($date);
    $date->modify('+1 day');
    $this->date = $date;
}
Run Code Online (Sandbox Code Playgroud)


Atr*_*eur 5

一个OOP原则是封装.类负责此类中包含的所有变量.

通过设置公共变量,您打破了这个原则.

通过创建一个存取器(setter),你可以通过在类之外更改该值来间接破坏该原理.

getter的优点是调用方法不需要关心如何检索数据.它只知道它将获得预期的数据,而这就是全部.这里封装原则受到尊重.

setter的优点是类在应用之前有机会检查新值.在一个完美的世界中,不需要访问器,因为一个类可以完全管理他的所有变量.在现实世界中,有时您需要设置一个值或从外部获取它.

接近完美世界的最佳方法是将加速器仅限于极少数必须修改的变量.如果可能,检查设定值.

关于你的例子,第二个解决方案更好,因为你在PHP堆栈中保存一个级别.您的访问器是无用的,因为您的变量无论如何都是公共的(因此,没有封装)并且不执行任何附加检查.但是在可能的情况下,您应该使用访问器来检查数据.如果您的应用程序中的任何其他位置不需要该数据,则不要执行任何访问者.