Php 独立的getter/setter方法,还是组合的?

Php 独立的getter/setter方法,还是组合的?,php,oop,naming-conventions,kohana,getter-setter,Php,Oop,Naming Conventions,Kohana,Getter Setter,在一个项目中,我一直在做一些更改,并浏览现有的框架API文档以获取洞察力 在阅读Kohana文档时,我注意到任何给定类的getter/setter通常是组合的: public function someProperty($value = null){ if(is_null($value){ return $this->_someProperty; } $this->_someProperty = $value; return $this

在一个项目中,我一直在做一些更改,并浏览现有的框架API文档以获取洞察力

在阅读Kohana文档时,我注意到任何给定类的getter/setter通常是组合的:

public function someProperty($value = null){
    if(is_null($value){
        return $this->_someProperty;
    }
    $this->_someProperty = $value;
    return $this;
}
而不是:

public function setSomeProperty($value){
    $this->_someProperty = $value;
    return $this;
}

public function getSomeProperty(){
    return $this->_someProperty;
}
除了减少给定类的方法计数之外,这样做(前者)还有什么价值吗?我一直认为方法(一般的函数)应该更能描述一个动作。其他有经验的开发人员看到这一点时会畏缩吗,哪怕是有一点点


我只是惊讶地看到一个流行的框架使用了这样的约定(我当然没有使用Kohana)

我宁愿相信他们对这样做有一个合理的解释。例如,为了更容易地实现ArrayAccess。唯一确定的方法是直接问他们


要回答你的问题,是的,当我看到第一种方法时,我会畏缩。与OOP原则背道而驰。

如果你在任何地方都这样做,这是一个很好的方法,但是对于所有的东西来说,它确实需要这样做,也许这个框架的程序员已经习惯了(有点像jquery)

然而,这会让我困惑

对于设置和获取,我始终使用:


jQuery与Kohana的方式相同。不过,我认为最好创建单独的设置和获取方法。这种方法的作用更加明显,而且我认为它在ide中的代码完成方面更加实用。例如,键入
set
,您将获得一个可以设置的所有属性的列表

另一个缺点是:如果要将值真正设置为
null
,该怎么办?这不起作用,因为
null
是值中return的标识符,您在设置特定值时受到限制


这很好,因为你将不得不写得更少,但是嘿,在你的方法前面有三个字母(
set
/
get
)是什么呢?

尽管Kohana在OOP中使用了如此不同寻常的技术,我认为你应该首先遵循编码惯例。当然,最好对类中的每个属性使用单独的getter和setter。因此,如果有可能使用它们而不违反惯例——只要这样做,你就不会错;)。如果您对使用OOP技术有疑问,您也可以在这里阅读关于PHP OOP的好习惯。希望它会有所帮助:

< P>我认为这个坏的做法是因为它违反了。设置值就是更改状态(命令)。获取值就是请求状态(查询)。一个方法不应该同时做这两件事,而应该只做一件事

另外,当一个方法仅仅被称为username时,它的作用并不明显,例如没有动词,比如get或set。在您的示例中,情况更糟,因为返回值要么是对象本身,要么是属性值,因此不一致


此外,因为它们会很快使您的API变得复杂。您拥有的getter和setter越多,该对象的协作者就越需要关于该对象的知识。如果您发现您的对象询问其他对象有关其内部的信息,那么很可能您将责任放错了位置。

为什么不这样做

public function someProperty($value = null)
{
    if (func_num_args() === 1) {
        $this->someProperty = $value;
        return $this;
    } else {
        return $this->someProperty;
    }
}

这将是实现组合getter/setter的唯一正确方法

组合方法确实提供了一些好处:

  • 避免
    \uuu get
    \uu set
    魔术,同时仍模拟公共属性。(无论如何,我都不建议在这些情况下使用魔法)
  • 使用
    thing()
  • 尽管这些方法将做更多的事情,但它们仍然可以被视为“做一件事()”,即处理
    事情()
    。属性还做不止一件事。它们允许您设置和获取值
  • 有人认为
    thing()
    没有动词。但是,我们可以假设没有动词的
    thing()
    意味着我们将其用作属性(我们获取并设置它)。对于接口,我们可以说不带参数的
    thing()
    是只读的,带参数的
    thing($arg)
    是读/写的。我们为什么要羞于采纳这一点?在某种程度上,我们采纳了加入接受者和接受者的想法,不是吗
  • 如果您使用的是基于web的语言(如PHP),那么很可能您也在使用jQuery。JQuery已经在做这类
    事情()
    ,而且效果很好
  • 如前所述,使用
    func\u num\u args()
    ,有助于完美实现此方法

  • 就我个人而言,我在目前的应用程序中已经承担了很大一部分风险,所以我可能会使用久经考验的getter和setter()。我想我们已经受过训练,可以查找这些get/set前缀(以及我们的IDE),以查看我们可以在类中使用哪些属性。这是一个我愿意在某个时候重新讨论的话题。

    请注意,这在javascript框架中被广泛使用,可能是因为Kohana的代码远远不够理想。这不仅仅是因为setter/getter。即使将setter和getter组合到一个方法中,在这种情况下,也是错误的(IMHO)。与其检查
    是否为空($value)
    ,不如检查
    func\u num\u args()==0
    。问得好。尽管Kohana将其用于其内部库,但您可以根据需要在模型中使用getter和setter。这非常适用于Kohana内部库,但也不能用于代码中。我不认为这是Kohana的编码标准。有一个编码标准页面,但是没有关于这个案例的任何信息。这种方法的PHPDOC块看起来一定很糟糕!谢谢@faileN-你的三点都击中了我的顾虑。方法链接自动完成被可能的任意返回值(
    null)所掩盖
    
    public function someProperty($value = null)
    {
        if (func_num_args() === 1) {
            $this->someProperty = $value;
            return $this;
        } else {
            return $this->someProperty;
        }
    }