在Symfony中使用服务的主要优势是什么?

时间:2016-02-20 10:35:04

标签: symfony service dependency-injection

我是symfony的新手,我不明白使用服务的优势而不是在控制器中写cose

例如,我有一个创建日志的服务,其代码如下:

        $path = $root.'/../web';
        $fs->touch($path.'/log.txt');
        $this->file = $path.'/log.txt';
        file_put_contents($this->file, $msg, FILE_APPEND | LOCK_EX);

我可以使用DIC($ fs是FileSystem服务)使用此登录服务,或者我可以将此登录设置在我的控制器上。

当然如果我需要经常登录,我必须编写相同的代码。主要优点是去耦?

非常感谢

2 个答案:

答案 0 :(得分:1)

假设您有一个使用 BasicLogger Bar 类。

您可以通过几种方式访问​​此记录器,让我们从最简单的选项开始:

<?php 

class Bar
{
    public function bar()
    {
        $logger = new BasicLogger();
        $logger->log("foo");
    }
}

这是不好的做法,因为我们将构造逻辑与应用程序逻辑混合在一起。它仍然有效,但它有以下缺点:

  • 它混合了责任。
  • 酒吧变得难以测试,无法在没有副作用的情况下进行测试。
  • 我们无法动态更改记录器(代码不太可重复使用)。

为了解决这些缺点,我们可以通过构造函数来要求我们的 Logger 类。

我们的代码现在看起来像这样:

class Bar
{
    private $logger;

    public function __construct(Logger $logger)
    {
        $this->logger = $logger;
    }

    public function bar()
    {
        $this->logger->log("foo");
    }
}

很好,我们的班级不再负责创建记录器,我们可以测试我们的代码而没有副作用(并根据记录器的使用方式进行断言),现在我们可以使用我们喜欢的任何记录器。

所以现在我们在整个应用程序中使用我们的新类。

$logger = new Logger();
$bar = new Bar($logger);

看起来很熟悉? 我们再次将构造逻辑与应用程序逻辑混合在一起,我们已经知道这很糟糕。

不仅如此,更糟糕的是发生在这里,代码重复。

多数民众赞成。每当我们想要使用我们的Bar类时,复制就会变得更糟。

解决方案?使用Service container

将您的记录器注册为服务意味着您需要记录功能的所有代码不再依赖于您的特定记录器,责任不会混淆,代码重复将减少,您的设计将变得更加灵活。

答案 1 :(得分:-1)

服务的主要目标和优势是保持可重用的代码并使用DRY方法。

当然,您在使用它们时会逐渐发现许多其他优势。

可以从应用程序的任何上下文访问服务,这些上下文可以访问服务容器,而不仅仅是控制器。

如果没有服务,您提供的几行代码将在多个方法/上下文中重复,您应该保留您的服务。
否则,删除它并在特定方法中执行逻辑。

我认为使用它们的更好方法是你自己的感觉 不要尝试在预防中创建服务,使用它们来解决实际需求。

当你有一个重复的代码块时,你应该自然地通过创建一个服务(或你的控制器可以扩展并继承代码块的其他AbstractController来避免它。

目标是:始终保持轻松的代码,尽可能避免重复 为此,您可以使用Symfony的强大服务,或者只使用类的继承和其他POO原则。