很多时候,我听说要避免静电类 ,因为它们将插入的依赖,这将使得你的代码在其他项目无法使用,并且不会允许单元测试 。
比方说,我们有一个典型的class DB
访问数据库,如果这样的类是static
,我们可以把它在我们的代码的地方:
DB::execQuery(...);
但是这创造依赖关系,因此,让DB类不是一成不变的,在这种情况下,我们将在我们的代码的地方:
$db = new DB();
然后我们就可以在我们的代码中调用
$db->execQuery(...);
但是现在使用的时候$db
一个内部function
,我们每次都需要首先声明它像这样
global $db;
有没有办法来解决这个?
一种方法可能是注入$db
对象在使用它的类,但我会在所有使用它的类注入它,这是ridicolous,静态类会更快一起工作,更少的代码编写。 我缺少的东西?
$ DB可以在实例注入属性,那么你就只需要访问,而不是围绕它传递给每个方法的这个属性。
class MyClass {
protected $_db; // DB Connection
public function __construct($db) {
$this->_db = $db;
}
public function foo() {
$this->_db->query('...');
}
}
除此之外,你可以看看具有改掉表现得像一个全局变量,但解决一些测试问题服务容器(又名依赖注入容器)。 看看其中的一些相关的问题
- 如果单身是坏的,那么为什么是一个服务容器好?
- 它是很好的做法,DI容器代替全局$注册表对象?
有一个DI容器,您可以使用静态方法在你的类像DI_Container::get('db')
它看起来像很多global
或其他一些静态调用的..但在这种情况下DI_Container
含有特殊的方法,允许用于测试和其他情况..消除一些全球“邪恶”的过程中必须采取额外的措施。
除了迈克B的答案,我想指出的是在你的代码错误的设计是:«我们可以把它无论在我们的代码»。
事实上,数据库只能由模型,或应用程序的小部分有了解数据库中使用。 因此,这些类应该知道有一个数据库,并使用它作为一个依赖(通过构造函数传递麦克乙说)。
但是,你的应用程序的其余不应该关心一个数据库,它应该只关心模型。 着眼于重构和收集所有访问该数据库到模型类的代码。
这样,你的应用程序将具有相关性的模型层:数据库对象/连接。 而应用程序的其余部分将使用模型,模型中任何发生在没有控制器/视图业务。
享受重构。
文章来源: PHP avoid static classes to avoid dependencies, but I need to use global everywhere