浅析PHP中Collection 类的设计_php教程-查字典教程网
浅析PHP中Collection 类的设计
浅析PHP中Collection 类的设计
发布时间:2016-12-29 来源:查字典编辑
摘要:用.net开发已经很多年了,最近接触到php,发现php也很好玩。不过发现它里面没有集合Collection类,只有数组,并且数组很强。这里...

用.net开发已经很多年了,最近接触到php,发现php也很好玩。不过发现它里面没有集合Collection类,只有数组,并且数组很强。这里我用数组来包装成一个集合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;

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

相关阅读
推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
  • 大家都在看
  • 小编推荐
  • 猜你喜欢
  • 最新php教程学习
    热门php教程学习
    编程开发子分类