Den*_*ovs 1 php frameworks design-patterns
我正在为一个项目构建某种迷你框架,并提出这个解决方案.我尝试了很多,但在我看来这非常方便(代码简化为了简化):
# Basically it's just a Registry pattern
class Repository {
private static $objects = array();
public function loadObject($alias, $object) {
self :: $objects[$alias] = $object;
return true;
}
public function __get($name) {
if ($this->objectExists($name)) {
return self::$objects[$name];
} else {
return false;
}
}
}
class Database extends Repository {
/* database class */
}
class Session extends Repository {
public function some_func($key, $value) {
/* i can access database object using $this in any class that extends Repository */
$this -> database -> exec (/* sql */);
}
}
/* =================== */
# Load core objects
$R = new Repository :: getInstance();
$R -> loadObject ('config', new Config());
$R -> loadObject ('database', new Database());
$R -> loadObject ('session', new Session());
/* =================== */
Run Code Online (Sandbox Code Playgroud)
你能看到这种方法有什么问题或缺点吗?对我来说,我可能会看到更多的内存消耗,因为每个下一个类都拥有来自Repository的越来越多的对象.在我有一个每个类都独立的设计之前,但无论如何所有这些都需要数据库,会话,配置等,所以我不必在任何类中声明它们.只是想注意,我只计划这个设计用于核心对象,而不是特定的类.
不要延伸Repository:
[...]如果S是T的子类型,则程序中类型T的对象可以用类型S的对象替换而不改变该程序的任何期望属性(例如,正确性).
编辑:尝试回答此回复中的后续问题.
这种技术称为依赖注入.会话示例:
class Session {
// notice the clean API since no methods are carried along from a possibly huge base class
public function __construct(ISessionStorage $storage) {
$this->_storage = $storage;
}
public function set($key, $value) {
$this->_storage->set($key, $value);
}
}
interface ISessionStorage {
public function set($key, $value);
}
class DatabaseSessionStorage implements ISessionStorage {
public function __construct(Db $db) {
$this->_db = $db
}
public function set($key, $value) {
$this->_db->query("insert....");
}
}
class CookieSessionStorage implements ISessionStorage {
public function set($key, $value) {
$_SESSION[$key] = $value;
}
}
// example where it's easy to track down which object went where (no strings used to identify objects)
$session = new Session(new DatabaseSessionStorage(new Db()));
$session->set('user', 12512);
// or, if you'd prefer the factory pattern. Note that this would require some modification to Session
$session = Session::factory('database');
$session->set('user', 12512);
Run Code Online (Sandbox Code Playgroud)
当然,您可以在配置文件中存储硬编码的连接设置.这只意味着其他文件需要获取该配置类而无需通过其父项.例如:
class Database {
// The same pattern could be used as with the sessions to provide multiple database backends (mysql, mssql etc) through this "public" Database class
public function __construct(Config $config) {
$this->_config = $config;
$this->_connect();
}
private function _connect() {
$this->_config->getDatabaseCredentials();
// do something, for example mysql_connect() and mysql_select_db()
}
}
Run Code Online (Sandbox Code Playgroud)
如果您希望保留配置信息不受php文件的影响(为了便于编辑/阅读),请参阅Zend_Config-classes以获取访问不同存储设备的示例,包括更常见的存储设备:ini,php array,xml.(我只是提到Zend_Config,因为我已经使用它并且很满意,parse_ini_file也会这样做.)
一个好的,希望很容易阅读:Fabience Potencier - 什么是依赖注入?
编辑#2:
另请参阅幻灯片:Matthew Weier O'Phinney - 构建您的模型
| 归档时间: |
|
| 查看次数: |
224 次 |
| 最近记录: |