php Collection種的設計

來源:互聯網
上載者:User
php Collection類的設計

用。net開發已經很多年了,最近接觸到php,發現php也沒好玩。不過發現它裡面沒有集合類,只有數組,並且數組很強。這裡我用數組來封裝成一個集合Collection,代碼如下:

class Collection{private $_members=array();public  function addItem($obj,$key=null){if($key){if(isset($this->_members[$key])){throw  new exception("Key \"$key\" already in use!");}else{$this->_members[$key]=$obj;}}else{$this->_members[]=$obj;}}public function removeItem($key){if(isset($this->_members[$key])){unset($this->_members[$key]);}else{throw new exception("Invalid Key \"$key\"!");}}public function getItem($key){if(isset($this->_members[$key])){return $this->_members[$key];}else{throw new  exception("Invalid Key \"$key\"!");}}public function Keys(){return array_keys($this->_members);}public function legth(){return sizeof($this->_members);}public function exists($key){return (isset($this->_members[$key]));}}
現在我們來測試一下這個集合是否好用。

我們首先建立一個集合元素類Course:

class  Course{private $_id;private $_courseCode;private $_name;  public function __construct($id,$courseCode,$name){$this->_id=$id;$this->_courseCode=$courseCode;$this->_name=$name;}public function getName(){return $this->_name;}public function getID(){return $this->_id;}public function getCourseCode(){return $this->_courseCode;}public function __toString(){return $this->_name;}}
測試代碼如下:

$courses=new Collection();$courses->addItem(new Course(1, "001", "語文"),1);$courses->addItem(new Course(2, "002", "數學"),2);$obj=$courses->getItem(1);print $obj;
我想這個集合類應該可以滿足我們平日開發的需求了吧。
可是我們現在。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如下:

class CourseCollection extends Collection { public function addItem(Course $obj,$key=null) {parent::addItem($obj,$key);}}class Student{private $_id;private $_name;public $course;publicfunction __construct($id,$name){$this->_id=$id;$this->_name=$name;$this->course=new CourseCollection();$this->course->setLoadCallback('loadCourses',$this);}public function getName(){return $this->_name;}public function getID(){return $this->_id;}public function __toString(){return $this->_name;}public function loadCourses(Collection $col){$col->addItem(new Course(1, "001", "語文"),1);$col->addItem(new Course(2, "002", "數學"),2);}}
調用代碼如下:

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


  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.