您的位置:首页 > 编程语言 > PHP开发

用PHP实现简单的IoC控制反转

2012-05-02 15:45 579 查看
我们讨论了关于IoC控制反转的设计原则,现在我们用PHP来实现IoC设计原则,加深对这个概念的理解。

首先编写 Fruit 的 POJO 和 Fruit 接口。继承 Fruit 接口生成两个类 Apple 和 Banana,这两个类都实现了接口的 showColor() 方法。

Fruit.php

<?php

/**
* @author  Gonn, http://www.nowamagic.net/ */
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;
}
}

?>

ClassFactory.php

类工厂实现了一些简单功能,能够解析指定的配置文件,并根据配置文件生成类,同时设置指定的属性值:

<?php

/**
* @author  Gonn, http://www.nowamagic.net/ */
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;
}
}
}
}

?>

config.json

//备注使用双反斜杆
[
{
//类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"
}
]
}
]

test.php

为类工厂指定上述配置文件。我们可以看见,对配置文件里的不同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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: