修改类以封装而不是继承
作者:互联网
我处理过的代码库具有从MDB2继承的databse类.这形成了所用MVC框架(自定义构建的事务)的基础,而模型又从db继承.
如我所知,其中有些人已经注意到了,这会导致一个很大的问题.每次实例化模型时,结果都是创建一个新的数据库连接.这显然是很浪费的.这也意味着我无法按预期使用事务,因为如果事务在模型的一个实例中启动,则其影响对于其他实例是不可见的,直到发生提交为止.
我的计划是更改db类以封装MDB2,而不是继承它,然后让它通过其singleton功能维护MDB2的单个实例.
但是,MDB2是一个包含许多方法的大型库,代码库中的许多高级内容取决于能否访问MDB2方法.
有没有一种方法可以封装MDB2类并向其传递调用,而无需修改高层,也不必为MDB2中的每个方法编写包装方法?
解决方法:
由于您尚未提供任何代码,因此这是一个盲目的建议,您可以使用很少的代码删除继承,同时保持完整的功能并确保MDB类仅实例化一次.
class Db
{
protected static $_mdb;
public function __construct()
{
if(self::_mdb === NULL) {
self::_mdb = new MDB;
}
}
public function __call($method, $args)
{
return call_user_func_array(array(self::_mdb, $method), $args);
}
}
基本上,这将使您的DB类成为MDB的装饰器.第一次实例化时,DB类将创建并存储MDB的静态实例.这将在所有DB实例(包括子类)之间共享.这里没有理由使用Singleton.
__call拦截器将确保您在DB中调用的,调用MDB方法上的方法的任何方法都将被捕获并委派给MDB实例.魔术方法可能会严重影响性能,因此,当您注意到任何性能影响时,请将任何被调用的方法添加到DB类并从那里进行委托.
不用说,这仍然不是最佳解决方案,因为您的数据库实例仍与模型类紧密耦合.如果您可以负担得起更多的重构,我建议将当前从数据库继承的所有类改为封装数据库实例(除非它们是ActiveRecords).然后,使用依赖注入使数据库实例可用.
标签:mdb2,php,singleton,encapsulation 来源: https://codeday.me/bug/20191010/1885824.html