2010-11-22 92 views
0

我已经交给的代码库使用的功能是一个从MDB2继承的数据库类。这构成了使用MVC框架(一个定制的事务)的基础,而模型又从db继承。修改一个类来封装而不是继承

正如我确信你们中的一些人已经注意到,这导致了一个相当大的问题。每次您实例化一个模型时,结果都会创建一个新的数据库连接。这显然很浪费。这也意味着我无法按预期使用事务,因为如果一个事务在模型的一个实例中启动,其效果对其他实例是不可见的,直到发生提交。

我的计划是更改db类来封装MDB2而不是继承它,然后让它通过其单例功能来维护单个MDB2实例。

但是,MDB2是一个有很多方法的大型库,代码库中的很多东西依赖于能够访问MDB2方法。

是否有方法来封装MDB2类并将调用传递给它,而无需修改更高层,也无需为MDB2中的每个方法编写包装器方法?

+0

请问您可以展示一个示例模型类,以便我们可以看到它们的耦合程度? – Gordon 2010-11-22 10:35:26

回答

3

因为您还没有提供任何代码,所以这是一个盲目的建议,您可以用很少的代码去除继承,同时保持完整的功能并确保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的静态实例。这将在任何数据库实例中共享,包括子类。在这里没有理由使用Singleton。

__call拦截器将确保您在DB中调用的方法将被捕获并委派给MDB实例。魔术方法可能会对性能造成严重影响,所以当您发现任何性能影响时,请将所有调用的方法添加到数据库类并从中进行委派。不用说,这仍然不是最好的解决方案,因为你的数据库实例仍然与你的模型类紧密耦合。如果你可以承受更多的重构,我会建议让当前从DB继承的所有类封装数据库实例(除非它们是ActiveRecords)。然后使用依赖注入来使数据库实例可用。

相关问题