zoukankan      html  css  js  c++  java
  • 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);

     

  • 相关阅读:
    [自创]mootools所有复选框只能选择一个的功能
    tomcat设置https访问
    更改tomcat运行时标题
    Java日期操作: 查找星期一和星期天
    mysql 常用数据查询
    git pull代码冲突
    antd model form数据不刷新问题
    前端开发常见面试题
    whistle 使用步骤
    windows 环境 启动报错 '.inconfig' 不是内部或外部命令,也不是可运行的程序
  • 原文地址:https://www.cnblogs.com/majiang/p/2783779.html
Copyright © 2011-2022 走看看