【问题标题】:Handle order dependence in loops处理循环中的顺序依赖
【发布时间】:2010-05-15 09:28:33
【问题描述】:

我正在制作一个模板系统,我在其中使用 foreach 循环实例化每个标签。问题是一些标签相互依赖,所以我想知道如何绕过循环中的排序。

这是一个例子:

Class A {
  public $width;
  __construct() {
     $this->width = $B->width; // Undefined! Or atleast not set yet..
  }

}

Class B {
  public $width;
  __construct() {
     $this->width = "500px";
  }
  __tostring() {
      return "Hello World!";
  }
}

Template.php

$tags = array("A", "B");
foreach ($tags as $tag) {
   $TagObj[$tag] = new $tag();
}

echo $TagObj['A']->width; // Nadamundo!

编辑:好吧,澄清一下.. 我的主要问题是 A 类依赖于 B 类,但 A 类在 B 类之前实例化,因此尚未定义宽度在 B 类中。我正在寻找一种好方法来确保为每个人加载所有类,从而允许存在相互依赖关系。为了以后,请不要考虑任何语法错误..我只是当场编造这个例子。还假设在 B 类实例化后,我可以从 A 类访问 B 类。

我知道这在其他地方有应用,我确信这已经解决了,如果有人能启发我或指出我正确的方向,那就太好了!

谢谢! 马特·穆勒

【问题讨论】:

  • 我不明白。您希望按照什么标准进行实际排序?
  • 查看编辑了解更多详情
  • 您可以将对象实例化顺序添加到您的标签数组吗?像 $tags = array("A" => 1, "B" => 2);并在foreach之前按顺序排序?还是在您的系统中不可能?

标签: php class for-loop


【解决方案1】:

最简单的方法可能是在标记对象数组全部实例化后对它们进行第二次传递,并在每个标记对象上调用一些标准方法(参见模板方法模式,例如http://java.dzone.com/articles/design-patterns-template-method),例如

$tags = array("A", "B");
foreach ($tags as $tag) {
   $TagObj[$tag] = new $tag();
}

foreach (array_keys($TagObj) as $tagName) {
   $TagObj[$tagName]->resolveDependencies($TagObj);
}

resolveDependencies 的实现方式因类而异。

【讨论】:

    【解决方案2】:

    A::construct() 中的 $B 实例从何而来?它不在范围内。

    可能的解决方案:
    1) 静态值:

    class B {
        static $width = '500px';
    ...
    
    class A {
        function construct(){
            $this->width = B::$width;
         }
    

    2) 静态函数:

    class B {
        static function width(){
             return '500px';
    ...
    
    class A {
        function construct(){
            $this->width = B::width();
         }
    

    3) 及时工厂方法(或对象,如果你需要一个),如果你需要对象

    function getTag($name){
        global $TagObj;
        if(!isset($TagObj[$name]) && class_exists($name)){
             $TagObj[$name] = new $name();
        }
        return $TagObj[$name];
    }
    
    class A {
        function construct(){
            $this->width = getTag('B')->width();
         }
    ....
    $tags = array("A", "B");
    foreach ($tags as $tag) {
       $TagObj[$tag] = getTag($tag);
    }
    

    如果您希望 B 中的更改反映在 A 中,您始终可以使用引用而不是分配。当然,所有这些都希望类定义可用,如果没有,则定义一个 __autoload() ,或者预先包含它们。

    【讨论】:

      【解决方案3】:

      您在A$this->width = $B->width(); 中调用的B 类中缺少width() 方法(并且您应该包括或使用继承来在A 类中使用B 类)

      Class B {
        private $width;
        __construct() {
           $this->width = "500px";
        }
        __tostring() {
            return "Hello World!";
        }
      
        function width() {
         return $this->width;
        }
      }
      

      至于订购,你应该更具体。

      【讨论】:

      • 感谢您的回复。请阅读我的编辑以进行澄清。语法错误是我的错,但除此之外。
      猜你喜欢
      • 1970-01-01
      • 2011-07-26
      • 1970-01-01
      • 2015-07-06
      • 1970-01-01
      • 2014-09-22
      • 2012-06-07
      相关资源
      最近更新 更多