搓纹 [英] Cahining pattern

查看:98
本文介绍了搓纹的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在php中有一个可以使用链接方法的类,但是问题是我想按某种顺序链接方法。

I have a class in php that works with the chainning method, but the problem is that I want to chain the methods in some order.

class Chain {
  public function foo () {
    return $this;
  }
  public function bar () {
    return $this;
  }
  public function some () {
    return $this;
  }
}

因此,如果我使用此类,则可以以9种不同的方式将此方法链接起来(所有可能的3个元素的组合)

So, if I use this class, then I can chain this methods in 9 different ways (all the possible combinations of 3 elements)

但是,如果我确定方法 some 是否始终必须链接到 foo bar 之后,而不是以其他方式链接?

But what happen if I determine that the method some always must to be chained after foo or bar and not in other way?

$chain = new Chain();
$chain->foo->bar(); //works; i.e: the method some is optional
$chain->foo()->bar()->some(); //works
$chain->bar()->foo()->some(); //works
$chain->some()->bar()->foo(); //throws an exception

我认为我可以执行此设置布尔值,例如:方法 foo bar 被调用,然后将值设置为 true ,并且当开发人员调用 some 函数时,如果该变量为 false ,则抛出

I think that I can do this setting boolean values, something like: when the method foo or bar are called, then I set the value to some var to true, and when the developer calls the some function, if that var is false, then throws an exception, otherwise is allowed to continue.

但是我需要一些更优雅的东西,例如模式或内置解决方案。

But I need something more elegant, such as pattern or a built-in solution.

还有另一种方法吗?

推荐答案

我想象的非常粗糙的示例仍然会有一些内容每种方法中的代码数量

The very rough example I imagine will still have some lines of code in each method

<?php
class Chain {

  private $_register = array();

  public function foo () {
    $this->register(__METHOD__);
    return $this;
  }
  public function bar () {
    $this->register(__METHOD__);
    return $this;
  }
  public function some () {;
    $this->verify('foo'); // foo() should be called before some();
    $this->register(__METHOD__);
    echo 'it\'s ok';
    return $this;
  }
  public function verify($method) {
      if(array_key_exists($method, $this->_register) && $this->_register[$method] == true) {
          return true;
      }
      else {
          throw new Exception('Some exception');
      }
  }
  public function register($method) {
      $method = str_replace(__CLASS__.'::', '', $method);
      $this->_register[$method] = true;
  }
}

我们在这里做什么-我们有 register() verify()方法。 (它们可以是助手,但是出于当前的目的,我在类中添加了它们。

What do we do here - we have a register() and verify() methods. (they can be helpers, but for the current purpose I added them in the class.

每个方法在向其自身返回值之前都应具有一个方法。调用<$ c foo()中的$ c> $ this-> register(__ METHOD __)将添加到私有数组'foo中'=> true
verify()方法检查是否 foo 作为数组键存在,并且其值为 true 。如果为-,脚本将继续;否则-引发异常。

Each method should have before it's returning value a register to itself. Calling $this->register(__METHOD__) from foo() will add in the private array 'foo' => true. The verify() method checks if foo exist as array key and if its value is true. If it is - the script will continue. Otherwise - throws exception.

在这种情况下:

$chain = new Chain();
$chain->bar()->some()->foo(); //throws an exception




致命错误:...中出现未捕获的异常 Exception,并在消息中显示某些
异常。

Fatal error: Uncaught exception 'Exception' with message 'Some exception' in ...



$chain = new Chain();
$chain->foo()->some()->foo(); // ok




还可以

it's ok

这里的问题是我们建立了一个公约。您需要将 __ METHOD __ 传递给寄存器函数,因此在替换类名之后,它将仅在数组中添加方法名。因此,稍后,在需要验证是否已调用一个或多个函数的函数中,需要将方法名称用作字符串,即 $ this-> verify('foo');

The problem here is that we establish a "convention". You need to pass __METHOD__ to the register function so after it replace the classname it will add only the method name in the array. So later, in the function where you need to verify if one or more functions are called before this, you need to use the method name as string i.e. $this->verify('foo');

当然,您可以播放不同的场景而无需使用 strpos()进行剥离和测试在方法名后的(),以便在验证方法或其他方法时更容易识别。

Ofcourse you can play different scenarios without stripping and testing with strpos() or adding () after the methodname for easier recognition if you are verifying a method or smth else.

但至少要这样将使您不必为每种方法都填充不同的变量,即

But at least it will save you from making for each method, different variable to fill i.e.

function foo() {
    $this->_foo = true;
    return $this;
}
function bar() {
    $this->_bar = true;
    return $this;
}

这篇关于搓纹的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆