注意:我在我的问题中引用了很多Symfony控制台组件,但我认为如果考虑在任何用户界面的上下文中,这个问题可以被认为是更广泛的。
我正在使用Symfony Console component
来创建控制台应用程序。我试图将类耦合保持在最低限度,因为它使单元测试更容易,并且通常是更好的实践。
我的应用程序有一些可能需要一些时间才能完成的过程,因此我希望在运行时使用进度条和常规文本输出让用户知道发生了什么。 Symfony需要将Symfony
Console OutputInterface的实例传递给任何命令的execute方法。到现在为止还挺好;我可以随意创建进度条和输出文本。但是,我的应用程序的所有繁重工作并没有发生在命令中。执行方法,而是在我的应用程序的核心类中。这些课程不应该知道它们正在控制台应用程序中使用。
我正在努力保持这种方式,因为我不知道如何在不将输出类注入我的核心的情况下向控制台(或任何用户界面)提供反馈。这样做会导致控制台输出类与我的应用程序核心之间的紧密耦合。我曾考虑使用事件调度程序(Symfony有一个),但这也意味着我的核心将与调度程序相结合(也许那很好)。理想情况下,我需要排序" bubble"我的应用程序状态备份到调用命令的execute方法,然后我可以执行输出。
有人能指出我正确的方向吗?我觉得这实际上必须是一个很常见的案例,但却无法找到它。
感谢您提前的时间!
答案 0 :(得分:3)
之前我成功使用了事件调度程序方法。例如,您可以在处理的开始,进度和结束时触发事件,并让事件监听器根据该事件更新进度条。
<?php
$progress = $this->getHelperSet()->get('progress');
$dispatcher = $this->getContainer()->get('event_dispatcher');
$dispatcher->addListener('my_start_event', function (GenericEvent $event) use ($progress, $output) {
$progress->start($output, $event->getArgument('total'));
});
$dispatcher->addListener('my_progress_event', function () use ($progress) {
$progress->advance();
});
$dispatcher->addListener('my_finish_event', function () use ($progress) {
$progress->finish();
});
如果您真的想避免在服务中耦合事件调度程序,您可以扩展或修饰您的类(可能实现共享接口),并且只在那里使用事件调度程序。您需要在基类中使用扩展点(公共或受保护的方法),以便能够通知任何进度。