用。net开发已经很多年了,最近接触到php,发现php也很好玩。不过发现它里面没有集合Collection类,只有数组,并且数组很强。这里我用数组来包装成一个集合Collection,代码如下:

现在我们来测试一下这个集合是否好用。

我们首先建立一个集合元素类Course:

测试代码如下:
courses=newCollection();courses->addItem(new Course(1, "001", "语文"),1);
courses>addItem(newCourse(2,"002",""),2);obj=courses>getItem(1);printobj;
我想这个集合类应该可以满足我们平日开发的需求了吧。
可是我们现在。net里面有个对象延迟加载,举个例子来说吧,假如现在有Student这个对象,它应该有很多Course,但是我们希望在访问Course之前Course是不会加载的。也就是说在实例化Student的时候Course个数为0,当我们需要Course的时候它才真正从数据库读取相应数据。就是需要我们把Collection做成惰性实例化。
修改后的Collection代码如下:

复制代码
class Collection {

  private $_members = array();    //collection members

  private $_onload;               //holder for callback function

  private $_isLoaded = false;     //flag that indicates whether the callback
                                  //has been invoked

  public function addItem($obj, $key = null) {
    $this->_checkCallback();      //_checkCallback is defined a little later
        
    if($key) {
      if(isset($this->_members[$key])) {
        throw new KeyInUseException("Key \"$key\" already in use!");
      } else {
        $this->_members[$key] = $obj;
      }
    } else {
      $this->_members[] = $obj;
    }
  }

  public function removeItem($key) {
    $this->_checkCallback();
    
    if(isset($this->_members[$key])) {
      unset($this->_members[$key]);
    } else {
      throw new KeyInvalidException("Invalid key \"$key\"!");
    }  
  }
  
  public function getItem($key) {
    $this->_checkCallback();
    
    if(isset($this->_members[$key])) {
      return $this->_members[$key];
    } else {
      throw new KeyInvalidException("Invalid key \"$key\"!");
    }
  }

  public function keys() {
    $this->_checkCallback();
    return array_keys($this->_members);
  }

  public function length() {
    $this->_checkCallback();
    return sizeof($this->_members);
  }

  public function exists($key) {
    $this->_checkCallback();
    return (isset($this->_members[$key]));
  }

  /**
   * Use this method to define a function to be 
   * invoked prior to accessing the collection.  
   * The function should take a collection as a 
   * its sole parameter.
   */
  public function setLoadCallback($functionName, $objOrClass = null) {
    if($objOrClass) {
      $callback = array($objOrClass, $functionName);
    } else {
      $callback = $functionName;
    }
    
    //make sure the function/method is valid
    if(!is_callable($callback, false, $callableName)) {
      throw new Exception("$callableName is not callable " . 
                          "as a parameter to onload");
      return false;
    }
    
    $this->_onload = $callback;
  }
  
  /**
   * Check to see if a callback has been defined and if so,
   * whether or not it has already been called.  If not,
   * invoke the callback function.
   */
  private function _checkCallback() {
    if(isset($this->_onload) && !$this->_isLoaded) {
      $this->_isLoaded = true;
      call_user_func($this->_onload, $this);
    }
  }
}
复制代码

所需的Student如下:

调用代码如下:

student=newStudent(1,"majiang");printstudent->getName();
print $student->course->getItem(1);

 

点赞(0)

评论列表 共有 0 条评论

暂无评论
立即
投稿
发表
评论
返回
顶部