PHPで簡単なIoC制御反転を実現

4011 ワード

IoC制御反転の設計原則について議論し,ここではPHPを用いてIoC設計原則を実現し,この概念の理解を深める.
まずFruitのPOJOとFruitインタフェースを作成します.Fruitインタフェースを継承して2つのクラスAppleとBananaを生成し,この2つのクラスはいずれもインタフェースの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