PHP:获取所有类的连接和记录器对象的最佳方法

时间:2015-07-16 16:29:17

标签: php symfony oop

我有三个类,我将它们用于应用程序中的所有其他类:Connection,Logger和User(当前用户信息)。

我做了什么,我创建了一个基类,它在构造函数中实例化这三个类(我使用Symfony,因此Connection和Logger作为服务被检索)。 所有其他类都继承了Base Class,并且不必担心连接和记录器的内容。

我知道这不是一个好方法,因此无法继承其他课程。此外,它很难测试,因为对象是在构造函数中创建的。

我尝试过的另一种方法是将这些类依赖注入基类,所以我至少可以测试它们。 但是,如果我走这条路线,每次创建一个对象时,我必须先创建Connection和Logger并将它们传递给构造函数,这使得创建对象非常麻烦。

我知道Symfony依赖注入容器,但不幸的是,我不仅使用Symfony的类,还使用旧的Drupal项目,所以我想我无法使用它。

简而言之,问题是如何以一种易于使用和可测试的方式在整个应用程序中使用您的连接和记录器。

编辑:我现在使用的基类I示例:

class BaseModel {
    protected $connection;
    protected $logger;

    public function  __construct() {
        $kernel = $this->getKernelInstance();
        $this->connection = $kernel->getContainer()->get('database_connection');
        $this->logger = $kernel->getContainer()->get('logger');
    }

    public static function getKernelInstance() {
        ...
    }
}

2 个答案:

答案 0 :(得分:1)

你自己回答了这个问题:依赖注入。您也可以安全地使用容器。 Symfony是一组可重用的组件,它们以分离的方式构建,以便您可以在Drupal项目中的任何地方使用它们。事实上,Drupal 8是在Symfony组件之上构建的,包括依赖注入组件及其容器。此外,您可以使用other容器,也可以创建自己的容器。

答案 1 :(得分:1)

解决方案的

Factory模式:

工厂对象可以响应非平凡对象的创建和初始化。你的情况就是使用它的一个主要例子。

在您的示例中,您必须创建各种模型对象,这些对象需要记录器,数据库连接和用户对象。这可以由工厂完成。如果构造函数签名足够可预测(似乎是这种情况),那么你甚至不必为每个类创建不同的工厂,因为在PHP中你可以创建只有new $className($connection, $logger, $user)的新对象。

DI的职责是将连接,记录器和用户注入工厂。顺便说一句,DI还允许您使用容器中的任何对象作为factory来创建服务。

您还可以考虑使用标记接口自动执行setter注入。 DI可以配置为扫描实现*Aware接口的所有服务对象(ContainerAware和LoggerAware以这样做而闻名),并对它们执行setter注入。 Check out this blog post for details

为了提高可测试性,我还建议为您的工厂类创建一个接口,以便进行交换(也称为抽象工厂模式)。