服务之间应该如何通信? [英] How should services communicate between each other?

查看:96
本文介绍了服务之间应该如何通信?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

虽然从@tereško的答案中学到了如何构建模型,但我找不到最好的模型服务之间的通信方式.我还找到了答案,这与我正在处理的情况类似,但该示例非常适合展示.因此,从这种意义上讲,例如,当服务只能访问域和映射器工厂对象时,该如何在Blog服务内部检索识别服务.我可以从控制器发送吗?还是我也需要发送服务工厂?

While learning from @tereško's answer on how should a model be structured, I can't find what is the best way for communication between the services. I also found this answer which is a similar situation I'm dealing with, but the example is great for showcase. So, in that sense, how do I retrieve the recognition service inside of a Blog service for example, when the service has only access to a domain and mapper factory objects. Do I send it from the controller? Or do I need to send a service factory too?

更新: 我没有提供示例,因为我提到了tereško的第二个答案与我要达到的目标非常相似.我试图建立一个BlogService,例如存储一个帖子.为了存储帖子的作者,我试图检索(他称为)识别服务,以便获得登录的用户(显然是帖子的作者).

Update: I did not provide an example since I mentioned that the second answer of tereško is pretty similar to what I am trying to achieve. I am trying to build a BlogService that for example stores a post. In order to store the author of the post, I am trying to retrieve the (his called) recognition service in order to get the logged in user (which is apparently the author of the post).

class BlogService
{
    public function storePost($title, $content)
    {
        $post   = $this->domainFactory->build('Post');
        $mapper = $this->mapperFactory->build('Post');

        $post->setTitle($title);
        $post->setContent($content);
        $post->setAuthor( /* get logged in user */ );

        $mapper->save($post);
    }
}

推荐答案

理论

因此,基本上您的问题是如何与某些内容服务共享来自识别服务的域对象?" .实际上,我已经思考了一段时间.

The theory

So basically your question is "how to share a domain object from Recognition service with some Content service?". I have been actually thinking on this for some time.

如我所见,这里有4个选项.两种卑劣,一种很好,一种介于两者之间:

As I see it, there are 4 options here. Two shitty, one good one and one in-between:

  1. 先前提到的通过服务工厂"方法.

  1. Previously mentioned "pass the service factory" approach.

这是最幼稚的解决方案,因为在现实世界中,对象图的增长最终将变得不可控制-包含服务的服务包含服务.

This is the most naive solution, because in a real world situation you will end up with uncontrollable growth for the object graph - service containing services containing services .. ad nauseum.

这是不可持续的,但是很快.

It's unsustainable, but quick.

  • 以这种方式更改识别服务,使其将Account实例发回给控制器,然后该控制器又将其传递给其他服务.

  • Alter the Recognition service in such a way, that it spits back an Account instance to the controller, which then in turn passes is to other services.

    基本上,最终您将在各层之间造成有意的泄漏,以最大程度地减少复杂性.您可以将其称为体系结构非规范化".

    Essentially you would end up creating an intentional leak between layers in order to minimize complexity. You could call this "architectural denormalization".

    这是一个hack,架构很糟糕.

    It's a hack and a bad architecture.

  • 使用DI容器在服务之间共享域对象(甚至是映射器).

  • Use a DI container to share domain objects (and even mappers) between services.

    这种方式在前两个方面更为详尽,但也可以让您完全摆脱服务内部的工厂.

    This way is more elaborate previous two, but it also would let you get rid of the factories inside your services entirely.

    最佳选择,但需要其他技能和代码.

    Best option, but requires additional skill and code.

  • 使用域对象工厂仅创建一次Account实例(以及所有其他实例或选定实例).

  • Use your domain object factory to create the instance of Account (and either all others or selected ones) only once.

    Kinda类似于帖子,但适用于域对象.当然,您将需要某种方式来绕过缓存",因为一大批域对象将需要具有多次启动的能力.因此-需要一些配置.

    Kinda like in this post, but for domain objects. Of course you will need some way to also bypass the "cache", because a large group of domain objects will require an ability to be initiated more than once. Thus - a need for some configuration.

    一个棘手的中途解决方案,但可让您在服务中保持熟悉的API.

    A tricky half-way solution, but lets you keep familiar API within services.

  • 自白

    我本人当前正在使用选项2.其原因是我没有可以使用的DI容器(而我仅在5分钟之前想到了选项4").实际上,在"PHP DI容器"描述下看到的大多数内容实际上都是各种服务定位器(在这种情况下,无论如何,您最好还是有许多工厂).

    Confession

    I myself am currently using the option 2. The reason for it is that I don't have a DI container which I could use (and I thought of "option 4" only 5 minutes ago). Most of what you see under description "PHP DI container" are actually various service locators (in which case you are better off with bunch of factories anyway).

    如果您想使用DI容器,我的认可是 Auryn .

    If you want to go with DI container, my endorsement goes to Auryn.

    我自己不使用它的原因是,因为我真的很自大,所以我想制作自己的DI容器.

    And reason I am not using it myself is, because I am really arrogant, I want to make my own DI container.

    而不是这样写:

     $post->setAuthor($user);
    

    您应该这样写:

    $post->setAuthorId($user->getId());
    

    ..出于两个原因:

    • 您没有使用活动记录.因此,您不需要Post实例来管理它与其他实体的关系.这就是您要提供的服务.
    • 如果传递了整个Account实例,则无论如何都将最终提取ID.因此,您将违反《得墨meter耳法律》 ,没有任何实际好处.
    • You are not using an active record. Therefore you have no need for the Post instance to manage it's relations with other entities. That's what you have a service for.
    • If you passed the entire Account instance, you would end up extracting the ID anyway. So you would be violating Law of Demeter of no practical benefit.

    这篇关于服务之间应该如何通信?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆