为什么我实际上需要 Spring Boot 中的接口?

Kid*_*ler 5 java spring unit-testing spring-boot

在 Spring/Spring Boot 中编程时,常见的做法是让每个服务/组件实现一个接口,例如:

public interface IAdder {
    int add(int a, int b);
}

@Service
public class Adder implements IAdder {
    public int add(int a, int b) { return a + b; }
}
Run Code Online (Sandbox Code Playgroud)

如果我不打算为“Adder”功能提供多个实现,为什么我实际上需要编写该接口?

该问题的一个常见答案是“您需要它在单元测试中进行模拟”。对此,我可以回答——不完全是。我可以使用您能想到的所有可能的模拟框架(例如 Mockito)来模拟加法器:

@Autowired
IMultiplier multiplier;  // Class under test

@Mock
IAdder adder;

@Test  // Assuming I implement multiplication by multiple additions
public void multiplicationTest() {
    // Arrange
    when(adder).add(3, 3).thenReturn(6);
    
    // Act
    int result = multiplier.multiply(3, 5);
    
    // Assert
    verify(adder, times(4)).add(3, 3);
    assertThat(result).isEqualTo(15);
}
Run Code Online (Sandbox Code Playgroud)

话虽如此,IAdder接口能为我提供什么优势呢?

小智 0

如果您没有计划实现服务的多种选项,那么理论上您可以不使用接口。

但是,如果您使用单元测试,事情就会复杂得多。在单元测试中并不总是可以使用有效的实现(例如,如果您正在使用数据库连接或与外部应用程序交互)。

因此,最好使用接口。在您的问题中,您给出了无需模拟对象即可完成的最简单的情况。但这并不总是可能的。