【问题标题】:PHP chaining of methods and CLONEPHP 链接方法和 CLONE
【发布时间】:2014-03-20 03:51:05
【问题描述】:

我对某事感到好奇。

一位受人尊敬的开发人员建议使用“return clone $this”而不是简单地使用“return $this”,他最终离开了开源项目一段时间,并没有回答我的“为什么?”问题所以我很好奇它是否有任何好处。

所以作为一个普通的可链接方法的例子,我们可能会有这样的事情:

function setProperty($arg) {
    this->property = $arg;
    return $this;
 }

他的例子更像这样:

function setProperty($arg) {
     this->property = $arg;
     return clone $this;
}

我的印象是他错了,因为它所做的只是在每一步都复制一个无法访问的对象。

所以如果我们用他的方法说有这样的事情......

class foo {
     public $value;
     function setA($arg) {
        $this->value = $arg;
        return clone $this;
     }

     function setB($arg) {
         $this->value = $arg;
         return clone $this;
     }

     function setB($arg) {
         $this->value = $arg;
         return clone $this;
     }

     function print() {
         print $this->value;
     }
}

我们有这样一行($obj 是类 foo 的实例):

$obj->setA('a')->setB('b')->setC('c')->print();

无论是使用克隆 $this 还是直接使用 $this,这都应该最终打印 c。

不过……

$obj->setA('a')->setB('b')->setC('c');
$obj->print();

应该打印 a 因为只有第一步会改变原始对象。第二步将更改从第一步克隆的对象,第三步将更改从第二步传递给它的对象。

但是如果你选择了:

$obj = $obj->setA('a')->setB('b')->setC('c');
$obj->print();

我相信这也会以任何一种方法打印 c 。

如果我们最初将 $value 声明为静态,那么所有这些不同的变体都应该打印 c。

如果我了解这些东西是如何工作的,我相信我是正确的,并且认为使用“return clone $this”而不是“return $this”绝对没有任何好处。还是我遗漏了什么,或者我的上述假设完全错误?

谢谢!

罗德尼

【问题讨论】:

    标签: php chaining method-chaining


    【解决方案1】:

    我认为您永远不会想要修改当前对象的状态然后返回一个克隆。相反,您将克隆 然后 修改。例如,

    class Foo {
         private $value;
    
         function setValue($arg) {
            $clone = clone $this;
            $clone->value = $arg;
            return $clone;
         }
    
         function printValue() {
             echo $this->value.PHP_EOL;
         }
    }
    

    这样你的对象就变得不可变了。

    示例用法:

    $a = (new Foo)->setValue('a');
    $b = $a->setValue('b');
    
    $a->printValue();
    $b->printValue();
    

    这将打印出来

    a
    b
    

    当您“修改”$b 时,$a 不会被弄乱。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-20
      • 1970-01-01
      • 1970-01-01
      • 2018-08-16
      • 1970-01-01
      • 2015-07-16
      • 1970-01-01
      相关资源
      最近更新 更多