在面向服务的体系结构中,映射程序调用服务是否是一种好习惯?

时间:2019-07-12 16:35:08

标签: java spring javabeans clean-architecture

我想知道在自定义对象映射器内部调用/注入(微)服务是否是一种好习惯。

此映射器将实体转换为DTO。在此DTO中,存在一个包含一些值的总和的字段(需要一些业务逻辑)。我定义了一种服务,以集中使用在许多其他地方使用的逻辑。

2 个答案:

答案 0 :(得分:2)

严格来说,从映射器调用服务并没有错,但是它确实向映射器添加了依赖关系,该映射器通常是一个纯对象(Plain Old Java Object,POJO),可以将一种类型的对象简单地转换为另一种类型。一种替代方法是将所需信息作为参数传递给映射器。例如,假设您当前的设计类似于以下内容:

public class Foo { /* ... */}
public class FooDto { /* ... */}

public class FooService {

    public FooResults getSomeResults() { /* ... */ }
}

public class FooMapper {

    private final FooService service;

    public FooMapper(FooService service) {
        this.service = service;
    }

    public FooDto convert(Foo foo) { 

        FooResults results = service.getSomeResults();

        // ... use results ...
    }
}

您可以将FooMapper作为参数传递给FooService方法,而不是使FooResults依赖于convert

public class FooMapper {

    public FooDto convert(Foo foo, FooResults results) {    
        // ... use results ...
    }
}

此方法的优点是FooMapper不再依赖于FooService。相反,调用convert方法的客户端必须具有对FooService的引用才能获取FooResults对象。

答案 1 :(得分:1)

映射器将一个数据结构转换为另一个数据结构。因此,它仅应依赖于这两个数据结构之一。

 +------------------+              +----------+           +------------------+   
 | data structure 1 |   <-----     |  mapper  |  ----->   | data structure 2 | 
 +------------------+              +----------+           +------------------+  

如果映射器使用服务,则它也依赖于该服务。这意味着它知道如何获取数据。我想您的映射器取决于具体的服务。因此,对于其中一种数据结构的更改以及对该服务的更改,映射器将受到影响。

 +------------------+              +----------+           +------------------+   
 | data structure 1 |   <-----     |  mapper  |  ----->   | data structure 2 | 
 +------------------+              +----------+           +------------------+  
                                        |
                                        V
                                   +----------+    
                                   |  service | 
                                   +----------+ 

模拟服务进行测试可能很困难。也许服务依赖某种存储库,或者它本身就是SQL。

通过引入一个从获取数据的方式中抽象出来的接口,使映射器独立于数据结构的源可能会更好。然后,您的服务可以实现该接口或创建一个简单的适配器。

 +------------------+              +----------+           +------------------+   
 | data structure 1 |   <-----     |  mapper  |  ----->   | data structure 2 | 
 +------------------+              +----------+           +------------------+  
                                        |
                                        V
                               +------------------+          +--------------+
                               |   Data1Provider  | <------  |   service    |
                               +------------------+          +--------------+

使用这种方法,可以通过引入如何获取数据的稳定抽象来逆转对服务的依赖性。这就是所谓的依赖反转。

它可能是一个看起来像这样的简单界面

 public interface Data1Provider {
      public FooResults getResults();
 }

可以轻松模拟该界面以进行测试。

另一种好的方法是在调用映射器之前简单地调用服务。只需将服务返回的数据传递给映射器即可。我不会在这里详细介绍,因为Justin Albano's的答案已经显示出来了。