我們討論了關於IoC控制反轉的設計原則,現在我們用PHP來實現IoC設計原則,加深對這個概念的理解。
首先編寫 Fruit 的 POJO 和 Fruit 接口。繼承 Fruit 接口生成兩個類 Apple 和 Banana,這兩個類都實現了接口的 showColor() 方法。
<?php /** * @author Gonn, http://www.bkjia.com/ */ interface Fruit { public function showColor(); } class Apple implements Fruit { private $color; function getColor(){ return $this->color; } function setColor($value){ $this->color=$value; } function showColor(){ echo "Apple Color:" . $this->color; } } class Banana implements Fruit { private $color; function getColor(){ return $this->color; } function setColor($value){ $this->color=$value; } function showColor(){ echo "Banana Color:" . $this->color; } } ?>
類工廠實現了一些簡單功能,能夠解析指定的配置文件,並根據配置文件生成類,同時設置指定的屬性值:
<?php /** * @author Gonn, http://www.bkjia.com/ */ class ClassFactory { private $arr_conf; function ClassFactory($config_file){ //讀取配置文件內容 $handle = fopen($config_file, r); $content = fread($handle, filesize($config_file)); fclose($handle); //去除注釋 $content=preg_replace("<\/\/.*?\s>","",$content); //轉成數組 $this->arr_conf=json_decode($content,true); } function getBean($class_id){ //查找匹配 $class_id 的類 while(true){ //挨個測試 $conf=each($this->arr_conf); //找不到,返回 null if($conf==false) return null; if(strcmp($class_id,$conf["value"]["id"])===0){ //如果匹配則裝入類文件 include_once($conf["value"]["class_file"]); //生成類的實例 //print_r($conf["value"]["class_name"]); $obj=new $conf["value"]["class_name"](); //查找被設置的屬性 $arr_prop=$conf["value"]["properties"]; while($prop=each($arr_prop)){ //生成屬性的設置方法 setXXX ,第一個字母大寫 $set_method="set". ucwords($prop["value"]["name"]); //調用設置方法,並設置預設值 $obj->$set_method($prop["value"]["value"]); } //找到第一個,返回實例 return $obj; } } } } ?>
//備注使用雙反斜桿 [ { //類ID,方便工廠查找 "id": "Apple", //類名 "class_name":"Apple", //類文件 "class_file":"Fruit.php", //屬性設置 "properties":[ { "name":"color", "value":"Red" } ] }, { "id": "Banana", "class_name":"Banana", "class_file":"Fruit.php", "properties":[ { "name":"color", "value":"Yellow" } ] } ]
為類工廠指定上述配置文件。我們可以看見,對配置文件裡的不同ID,返回了不同的類實例。調用每個實例的方法,分別輸出了Red和Yellow。可見,我們只需要改變配置文件的內容,就可以返回不同的類實例,而不需修改程序源代碼。這就實現了簡單的 IOC 或者 DI。
<?php include_once("ClassFactory.php"); $factory = new ClassFactory("config.json"); $fruit = $factory->getBean("Apple"); echo $fruit->showColor() .'<br />'; $fruit = $factory->getBean("Banana"); echo $fruit->showColor() .'<br />'; ?>
PHP是動態語言,利用一些語言特性,實現起來很簡單,也沒用到反射之類的概念。
程序運行結果
Apple Color:Red Banana Color:Yellow