我应该为每个 class 使用一个 getter / setter,还是为每个 属性 使用一个 getter / setter?

Should I use one getter / setter per class, or one getter / setter per property?

关于是否使用getters / setters(例如this popular one),我已经看到很多问题和答案,但我也看到了两个getters / setters 的不同风格,关于哪种模式更可取以及为什么的信息很少。第一种是使用 1 getter 和 1 setter 每个 class,通过命名方法或使用魔术方法(我的例子使用 PHP 因为这是我每天使用的,但我的问题适用于任何面向对象的语言)。

<?php
class Foo {

    private $bar;
    private $baz;

    public function get($property)
    {
        if (property_exists($this, $property))
            return $this->$property;
    }

    public function set($property, $value)
    {
        if (property_exists($this, $property))
            $this->$property = $value;
    }

}

第二种是每个属性

使用1个方法
<?php
class Foo {

    private $bar;
    private $baz;

    public function getBar()
    {
        return $this->bar;
    }

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

    public function getBaz()
    {
        return $this->baz;
    }

    public function setBaz($value)
    {
        $this->baz = $value;
    }

}

对于我的生活,我想不出任何理由为每个 属性 设置单独的方法。即使您需要单独验证,您也可以在一种方法中使用开关,例如:

<?php
class Foo {

    private $bar;
    private $baz;

    public function get($property)
    {
        if (property_exists($this, $property))
            return $this->$property;
    }

    public function set($property, $value)
    {
        if (property_exists($this, $property))
        {
            switch ($property)
            {
                case 'bar':
                    $this->validateBar($value);
                    break;
                case 'baz':
                    $this->validateBaz($value);
                    break;
            }
            $this->$property = $value;
        }
    }

    private function validateBar( & $value)
    {
        // do some validation...
    }

    private function validateBaz( & $value)
    {
        // do some validation...
    }

}

我是不是遗漏了什么或者是否需要每个 属性 的一种方法?每个 class 使用一个 getter / setter 是好习惯吗?

已提出的另一个选项是使用 getsetters,每个 属性 的单个函数或 get/set 值。我一直认为这违反了 SOLID 的单一责任原则,但由于它已作为下面的答案给出,我想我会更新问题以包含它。

IMO,每个 属性 使用一个 getter & setter 会好得多。这促进了对象的正确使用,因此不能在对象上使用无效的对象。

它还增强了对对象的理解,因为您可以轻松地看到对象的可用属性。还清楚哪些属性是只读的(即它有 getter 但没有 setter)。

建议每个属性使用setter / getter函数将class的各个字段封装成合适的函数,我们可以用一个[= class.

的构造函数中的 15=] 方法

你的第二个例子是一种常见的方式。例如,Symfony2 实际上为 ORM 实体创建了这样的 getters/setters。

产生更精简代码的另一个有趣的解决方案:Getsetters

  • 传递参数:Set-mode
  • 不传递任何参数:Get-mode
  • Return 在设置模式下:总是 $this

所以你这样编码(几乎像jQuery)

// Setting
$myobject->name('foo')
         ->age(26);
// Getting
echo $myobject->age();
class Foo {
    private $name;
    private $age;

    public function name($name = null) {
        if( ! is_null($name)) {
            $this->name = $name;
            return $this;
        } else {
            return $this->name;
        }
    }

    public function age($age = null) {
        if( ! is_null($age)) {
            $this->age= $age;
            return $this;
        } else {
            return $this->age;
        }
    }
}

我建议为每个 属性 使用单独的 getter 和设置器,因为您可以键入提示设置器,以及每个 [=12] 的文档块注释 return 值=],使代码更易于理解,并且在使用 IDE(自动完成、转到声明等)时更易于编辑。

我赞成第二种更口头的方式,但我认为这更像是一个品味问题。

每个 属性 使用 getters/setters 的优点是:

  • 其他团队成员更容易阅读和理解
  • 更容易找到特定 setter/getter
  • 的用法
  • 从您的 IDE
  • 中更容易 search/find getter/setter 方法
  • IDE 最好使用自动完成
  • 不确定,但可能对错误的静态分析更精确
  • 检查历史时更好地理解代码修订
  • 我想这比总是调用 property_exists()
  • 快一点
  • 你可以编写better/more精确的文档

此外,请记住,如果您总是使用 getters/setters,那么您也可以将属性设置为 public。

否则,使用 getters/setters 提供有限的访问权限(仅提供 getter)或其他行为,即 setBar($value) 将执行 $this->value = $value ; updateOtherData();