ホームページ >バックエンド開発 >PHPチュートリアル >phpコレクションのデザインの種類

phpコレクションのデザインの種類

WBOY
WBOYオリジナル
2016-06-13 13:05:17858ブラウズ

php Collectionクラスのデザインは

を使用しています。私は長年ネット開発をしてきましたが、最近phpに触れてみて、phpも面白くないことに気づきました。ただし、そこにはコレクション クラスはなく、配列だけがあり、配列は非常に強力であることがわかりました。ここでは配列を使用してコレクションにラップしています。コードは次のとおりです:

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]));
	}
}
それでは、このコレクションがうまく機能するかどうかをテストしてみましょう。

最初にコレクション要素クラスを作成します。 コース:

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;
このコレクション クラスは、日々の開発ニーズを満たすことができるはずだと思います。
しかし、ここにいます。たとえば、ネットに遅延読み込みオブジェクトがあります。たとえば、Student オブジェクトがある場合、多くのコースがあるはずですが、コースにアクセスする前にコースが読み込まれないことを望みます。つまり、Student をインスタンス化するとき、Course の数は 0 です。 Course が必要な場合、実際にはデータベースから対応するデータを読み取ります。 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);
    }
  }
}
必要な生徒は次のとおりです。

class CourseCollection extends Collection {
 public function addItem(Course $obj,$key=null) {
		parent::addItem($obj,$key);
	}
}
class Student{
	private $_id;
	private $_name;
	public $course;
	
	public	function __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);


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。