什么是反贪污层模式?
Eric Evans在他的《领域驱动设计》一书中把它定义为(强调是我的)。
......一个隔离层,为客户提供他们自己领域模型方面的功能。该层通过其现有的接口与其他系统对话,几乎不需要对其他系统进行修改。
在内部,该层根据需要在两个模型之间进行双向转换。
这种模式在交互时很有用。
- 与可能有不同语义的外部系统,或
- 与第三方系统或遗留的应用程序。
这个层允许我们的系统与另一个系统进行交互,而不被他们的设计所影响(或破坏),使我们的系统与外国的概念完全隔离。反腐败层通常使用Facade和Adapter设计模式的组合来实现。
它是如何工作的?
这听起来可能有点复杂,但其实并不复杂,在Go中,我们可以通过两种方式来实现这个层。
- 使用一个专门的服务,或者
- 使用一个包
在这两种情况下,我们的目标都是通过包装所有需要的代码,将交互隔离到上游系统,并进行我们需要的转换,以满足我们自己的领域模型。

- 下游服务发出请求,因此触发了对**反腐层(ACL)**的调用。
- ACL对收到的消息进行转换并创建一个新的请求。
- ACL接收来自上游服务的消息。
- ACL将收到的消息转换为我们的下游服务所使用的领域模型,并且
- 转换后的消息被送回。
如何在Go中实现反贪污层?
这篇文章所使用的代码可以在Github上找到。
实现这种模式的一种方法是创建一个使用该模式的服务的本地包,在这个例子中,我们假设访问两个传统的API,在这两种情况下,它们都返回温度值,特别是开尔文和华氏温度,但是我们的领域模型使用摄氏度,所以我们必须创建一个反破坏层,以防止他们的实现破坏我们。
反腐败层模式使用了Facade和Adapter设计模式的组合,因此,对于fahrenheit 包的代码如下。
5func New(country string) Fahrenheit {
6 return Fahrenheit{}
7}
8
9func (f Fahrenheit) Value() float64 {
10 return 85.5
11}
和kelvin 包的代码。
3func Calculate(country string) float64 {
4 return 306.15
5}
可以很容易地在anticorruption 包中实现为。
8func Kelvin(country string) float64 {
9 // C = K − 273.15
10 return kelvin.Calculate(country) - 273.15
11}
12
13func Fahrenheit(country string) float64 {
14 // C = (5.0/9.0) * (F-32)
15 return (5.0 / 9.0) * (fahrenheit.New(country).Value() - 32)
16}
并以简单的方式访问。
11func main() {
12 // ...
13
14 fmt.Println("anticorruption", anticorruption.Fahrenheit("COUNTRY1"))
15 fmt.Println("anticorruption", anticorruption.Kelvin("COUNTRY2"))
16}
因此,隐藏了上游的实现,并使我们的模型与我们使用的保持一致。摄氏度。
结论
反腐败层是一种防御性模式,旨在分离两个领域,我们的领域和我们需要访问的领域,它在与遗留系统以及第三方API合作时非常有用,因为它隔离了它们的实现,使我们的领域模型与我们必须满足的要求保持一致。