- <?php
- /*
- * Created on 2011-5-16
- *
- * To change the template for this generated file go to
- * Window - Preferences - PHPeclipse - PHP - Code Templates
- */
- //假設我們要創建要給類來動態調用Module對象,即該類可以自由加載第三
- //方插件並集成進已有的系統,而不需要把第三方的代碼硬編碼進原有的代
- //碼。要達到這個目的,可以在Module接口或抽象類中定義一個execute()
- //方法,強制要求所有的子類都必須實現該方法。可以允許用戶在外部XML配
- //置文件中列出所有Module類。系統可以使用XML提供的信息來加載一定數目
- //的Module對象,然後調用其中的execute().
- //
- // 然而,如果每個Module需要不同的信息來完成任務,應該怎麼做呢?
- // 這這種情況下,XML文件可以爲每個Module提供屬性鍵和值,Module
- // 的創建者可以爲每個屬性名提供setter方法。代碼要確保根據某個屬
- // 性名調用正確的setter方法。
- class Person {
- public $name;
- function __construct($name)
- {
- $this->name = $name;
- }
- }
- interface Module{
- function execute();
- }
- class FtpModule implements Module{
- function setHost($host){
- print "FtpModule::setHost():$host\n<br>";
- }
- function setUser($user)
- {
- print "FtpModule::setUser():$user\n<br>";
- }
- function execute()
- {
- }
- }
- class PersonModule implements Module{
- function setPerson(Person $person)
- {
- print "PersonModule::setPerson():{$person->name}\n<br>";
- }
- function execute()
- {
- }
- }
- class ModuleRunner {
- private $modules = array();
- private $configData = array(
- "PersonModule"=> array('person'=>'bob'),
- "FtpModule"=> array('host'=>'example.com','user'=>'anon' ));
- public function init()
- {
- $interface = new ReflectionClass('Module');
- foreach($this->configData as $modulename =>$params)
- {
- $module_class = new ReflectionClass($modulename);
- if(!$module_class->isSubclassOf($interface)){
- throw new Exception("unkown module type:$modulename");
- }
- $module = $module_class->newInstance();
- foreach($module_class->getMethods() as $method )
- {
- $this->handleMethod($module,$method,$params);
- }
- array_push($this->modules,$module);
- }
- }
- public function handleMethod(Module $module,ReflectionMethod $method,$params)
- {
- $name = $method->getName();
- $args = $method->getParameters();
- if(count($args)!=1 || substr($name,0,3)!="set") {
- return false;
- }
- $property= strtolower(substr($name,3));
- if(!isset($params[$property]) ){ return false;}
- $arg_class = $args[0]->getClass();
- if(emptyempty($arg_class) ){
- $method->invoke($module,$params[$property]);
- }else{
- $method->invoke($module,$arg_class->newInstance($params[$property]));
- }
- }
- }
- $test = new ModuleRunner();
- $test->init();
- ?>