【问题标题】:Return object instance with current state返回具有当前状态的对象实例
【发布时间】:2016-09-19 20:05:40
【问题描述】:

有什么区别

$this->state = $state;
return $this;

$instance = clone $this;
$instance->state = $state;
return $instance;

上下文:

class TestCase {

    /**
     * State
     */
    private $state;

    /**
     * Set state
     */
    function setState($state) {
        $this->state = $state;
        return $this;
        // Or
        // $instance = clone $this;
        // $instance->state = $state;
        // return $instance;
    }

}
$test = new TestCase;
$test->setState($state1)->setState($state2);

【问题讨论】:

  • 什么是区别,一个是$this,另一个是$this的克隆。克隆就像副本,它是重复的。如果您的意思是值相同,那么副本就是副本,如果您复制文件并重命名它的内容相同......是的,直到它们分歧。现在,如果您检查此spl_object_hash,它们就不一样了。
  • 您的示例中的唯一区别在于,如果您从不将状态应用于原始 this 而仅应用于克隆,那么它们显然已经分歧了。这就像复制文件,然后在不更改原始文件的情况下编辑复制的文件。克隆后它们变成 2 个独立的不同实体。
  • @ArtisiticPhoenix 我刚刚添加了我所在的上下文。感谢您的快速回复。
  • 我建议避免克隆,原因是你失去了“状态”,因为你基本上是在撒谎而不是改变原始对象,这可能会导致以后出现意外的值。想象一下添加一个方法getState,以及什么对象的状态。它不必要地使事情复杂化,并对代码的可读性产生负面影响。也就是说,在这种情况下,值将是相同的,但稍后您将使用 $test 而不是它的克隆。
  • 简而言之,这是没有意义的,因为您没有存储克隆,因此无法在调用设置之外维护该状态,这意味着您不妨只使用您原来的局部变量喂了方法开始。因为您没有保留克隆的状态。

标签: php this instance clone


【解决方案1】:

作为一个例子,如果你这样做

 $test = new TestCase;
 $test->setState(1)->setState(2);

 $test->getState();

那么您使用的是什么克隆,答案是否定的,因为$test 是从未真正设置过状态的原始对象。其他 2 个克隆在方法链的末尾被丢弃。

方法链可能会返回正确的值,但是如果你把对象$test放到不同的作用域,比如

function a(){
      $this->test = new TestCase;
      $this->test->setState(1)->setState(2);
}

function b(){
    echo $this->test->setState(3);
}

然后 test 从来不知道其他 2 个状态,正如我所说的那样,这是毫无意义的。

通常,如果您在设置一些初始值后分叉一个对象,您会想要克隆它。一个示例就像一个查询构建器,您可以在其中构建查询,然后克隆它以执行单独的查询以计算结果(例如减去限制或订单)

 $Qb = new QueryBuilder();
 $Qb->select('*')->table('posts')->where( 'published', '<', '2014-02-20' );

  //copy and diverge to count results,
 $tQb = clone $Qb;
 $tQb->select('COUNT(id) AS total');  
 $total = $tQb->getResult();

  // add limits to original instance.
 $Qb->limit('20');
 $rows = $Qb->getResult();

See 克隆将用于保存设置查询的初始部分,然后根据个人需要复制和分散它们。一来计算总结果 一来提取有限数量的结果。如果您对 where 子句等有多个连接和多个部分,这将很有用。

【讨论】:

    【解决方案2】:

    如果我没记错的话,克隆时会产生两个不同的对象。

    【讨论】:

    • 我不会说不同,因为克隆是副本,所以它是同一个对象,具有与原始对象相同的状态,但从那时起是一个单独的实例。
    • 谢谢!不,我只想返回一个具有当前状态的当前对象实例。
    猜你喜欢
    • 1970-01-01
    • 2012-10-21
    • 2013-11-26
    • 1970-01-01
    • 1970-01-01
    • 2011-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多