开发者

Handle order dependence in loops

开发者 https://www.devze.com 2022-12-31 09:44 出处:网络
I\'m making a templating system where I instantiate each tag using a foreach loop. The issue is that some of the tags rely on each other so, I\'m wondering how to get around that ordering from the loo

I'm making a templating system where I instantiate each tag using a foreach loop. The issue is that some of the tags rely on each other so, I'm wondering how to get around that ordering from the looping.

Here's an example:

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!

EDIT: Ok just to clarify.. My main problem is that Class A relies on Class B, but class A is instantiated before class B, so therefore width has not yet been defined in class B. I am looking for a good way to make sure all the classes are loaded for everyone allowing the interdependencies to exist. For the future, please don't consider any syntax errors.. I just made up this example on the spot. Also assume that I have access to class B from class A after class B gets instantiated.

I know this has applications elsewhere and I'm sure this has been solved before, if someone could开发者_开发百科 enlighten me or point me in the right direction that'd be great!

Thanks! Matt Mueler


The easiest way will probably be by making a second pass over the array of tag objects once they've all been instantiated, and calling some standard method (see template method pattern e.g. http://java.dzone.com/articles/design-patterns-template-method ) on each e.g.

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

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

How resolveDependencies is implemented will vary from class to class.


Where does this $B instance in A::construct() come from? It's not there in scope.

Possible solitions:
1) Static values:

class B {
    static $width = '500px';
...

class A {
    function construct(){
        $this->width = B::$width;
     }

2) Static functions:

class B {
    static function width(){
         return '500px';
...

class A {
    function construct(){
        $this->width = B::width();
     }

3) Just in time factorymethod (or object if you need one), if you need objects

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);
}

And if you want a change in B to reflect in A you could always use references instead of assignments. All this of course expects the class definition to be available, define an __autoload() if not, or include them all beforehand.


You are missing width() method in B class that you are calling in A class $this->width = $B->width(); (and you should include or sort of use inheritance to use B class in A class)

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

  function width() {
   return $this->width;
  }
}

As for ordering, you should be more specific.

0

精彩评论

暂无评论...
验证码 换一张
取 消