我工作过/见过一些 spring-hibernate Web 应用程序项目,它们具有与实际服务和 dao 类一样多的接口。
我一直认为这两个是拥有这些单一实现接口的主要原因:
-
Spring 可以将实际实现连接为给定类中的依赖项(松散耦合)
public class Person {
@Autowired
private Address address;
@Autowired
private AccountDetail accountDetail;
public Person(Address address, AccountDetail accountDetail)
{ // constructor
-
在单元测试时,我可以创建模拟类并单独测试类。
Address mockedAddress = mock(Address);
AccountDetail mockedAccountDetail = mock(AccountDetail);
Person underTestPerson = new Person(mockedAddress, mockedAccountDetail);
// unit test follows
但是,最近我意识到:
Spring 可以将具体的实现类连接为依赖项:
public class Person {
@Autowired
private AddressImpl address;
@Autowired
private AccountDetailImpl accountDetail;
public Person(AddressImpl address, AccountDetailImpl accountDetail) {
// constructor
像 EasyMock 这样的模拟框架也可以模拟具体类
AddressImpl mockedAddress = mock(AddressImpl);
AccountDetailImpl mockedAccountDetail = mock(AccountDetailImpl);
Person underTestPerson = new Person(mockedAddress, mockedAccountDetail);
// unit test follows
另外,根据this https://stackoverflow.com/questions/90851/is-it-just-me-or-are-interfaces-overused讨论中,我认为总结是,在单个应用程序中,界面大多被过度使用,可能是出于惯例或习惯。当我们与另一个应用程序交互时,它们通常最有意义,例如世界各地许多应用程序使用的 slf4j。在单个应用程序中,类几乎与接口一样是抽象。
所以,我的问题是为什么我们仍然需要接口,然后有像 *ServiceImpl 和 *DaoImpl 类这样的单一实现,并不必要地增加我们的代码库大小。模拟具体类是否存在我不知道的问题。
每当我和我的队友讨论这个问题时,我得到的唯一答案是基于接口实现服务和 dao 类是每个人遵循的设计 - 他们提到 Spring 最佳实践、OOP、DDD 等。但我仍然不知道在一个独立的应用程序中拥有如此多的接口背后有一个务实的理由。