这里答案之间的差异程度说明了为什么这是一个难以掌握的概念,但要尽可能简单地描述它:
为了让我知道如果我把球扔给你,那么你可以接住它,我真的不需要知道你多大了。我不需要知道你早餐吃了什么,我真的不在乎你的初恋是谁。我只需要知道你能抓到。如果我知道这一点,那么我不在乎是你我在向你或你的兄弟扔球。
对于像 c# 或 Java 等非动态语言,我们通过接口来实现这一点。假设我们有以下接口:
public ICatcher
{
public void Catch();
}
现在假设我们有以下类:
public CatcherA : ICatcher
{
public void Catch()
{
console.writeline("You Caught it");
}
}
public CatcherB : ICatcher
{
public void Catch()
{
console.writeline("Your brother Caught it");
}
}
现在CatcherA 和CatcherB 都实现了Catch 方法,因此需要Catcher 的服务可以使用其中任何一个,而不必真正在乎到底是哪一个。所以一个紧密耦合的服务可能会直接实例化一个被捕获的即
public CatchService
{
private CatcherA catcher = new CatcherA();
public void CatchService()
{
catcher.Catch();
}
}
所以CatchService 可能完全按照它的计划去做,但它使用CatcherA 并且始终使用CatcherA。它是硬编码的,所以它会一直留在那里,直到有人出现并对其进行重构。
现在让我们采用另一个选项,称为依赖注入:
public CatchService
{
private ICatcher catcher;
public void CatchService(ICatcher catcher)
{
this.catcher = catcher;
catcher.Catch();
}
}
因此,实例化 CatchService 的调用可能会执行以下操作:
CatchService catchService = new CatchService(new CatcherA());
或
CatchService catchService = new CatchService(new CatcherB());
这意味着Catch 服务没有与CatcherA 或CatcherB 紧密耦合。
还有其他几种松散耦合服务的策略,例如使用 IoC 框架等。