你可以返工你這樣的自動加載功能,所以誤差檢測,如果該文件不存在:
function __autoload($class) {
$parts = explode("\\", $class);
$path = implode(DIRECTORY_SEPARATOR, $parts) . ".php";
if (!file_exists($path)) {
throw new Exception("The class is not loadable");
} else {
include_once $path;
}
}
然後在工廠:
class ValidatorFactory {
public static function create($name) {
try {
/*
* try to include from the core namespace
*/
$Class = "core\\validators\\" . $name;
$validator = new $Class();
return $validator;
} catch (Exception $ex) {
/*
* if it's not possible, try to include from the app namespace
* if the validator doesn't exist at all, then we
* let the user handle the error
*/
$Class = "app\\validators\\" . $name;
$validator = new $Class();
return $validator;
}
}
}
,那麼你可以就像這樣使用它:
$myValidator = ValidatorFactory::create("EmailValidator");
在你的上下文中,我認爲它會更適合使用stat ic create()
,但也許我錯了。
您還可以記錄create()
方法的返回值,以便您的IDE(netbeans,eclipse,whatever)知道返回類型,並顯示建議(我想您的庫中有一個基本接口或抽象類,驗證):
/**
* @return \core\validators\IValidator
*/
public static function create($name) {
...
}
編輯:
你可以使用這樣的事情,但你需要創建工廠的情況下,這是不是在我看來,最好的辦法,但在這裏你去:
Abstr行事基類,有一個具體的實施create()
abstract class AbstractFactory {
private $namespaces = array();
public function __construct($namespaces) {
$this->namespaces = $namespaces;
}
public function create($name) {
foreach ($this->namespaces as $namespace) {
$Class = $namespace . "\\" . $name;
try {
$instance = new $Class();
return $instance;
} catch (Exception $ex) {
// empty
}
}
throw new Exception("No class found");
}
}
的實現
class ValidatorFactory extends AbstractFactory {
public function __construct() {
parent::__construct(array(
"app\\validators",
"core\\validators"
));
}
}
然後:
$factory = new ValidatorFactory();
$myValidator = $factory->create("MyValidator");
此外,當你進入命名空間的使用,你爲什麼會想退化爲通用名稱(無NS),還是希望應用程序名稱空間優先於核心框架?這會產生相當不可預測的結果。 – webmaster777
我已經在沒有工廠的情況下實現了這種模式,其中應用程序類正在擴展核心類,並且核心中也總是有類的應用程序版本。在實際應用程序中創建類時,它將覆蓋核心版本 –
可預測性是一個很好的觀點。現在當你說它的時候,當我不尊重它們時,定義命名空間似乎沒什麼意義...... – mightyplow