這三種設(shè)計(jì)模式同屬于結(jié)構(gòu)型模式,初學(xué)者乍一看可能難以分辨三者的區(qū)別。這里對(duì)三者之間的異同詳細(xì)地探討一下。
適配器模式VS裝飾模式
首先來(lái)比較一下適配器模式和裝飾模式。兩者都被稱為包裝模式,在功能上是較為接近的。

適配器模式分為類適配器和對(duì)象適配器。類適配器比較直接,繼承待適配類,實(shí)現(xiàn)目標(biāo)接口,使得待適配類滿足目標(biāo)接口的特定功能。但是這種直接繼承的方法太簡(jiǎn)單粗暴了,我們知道要盡量多聚合少繼承,所以更提倡使用下面的對(duì)象適配器。

對(duì)象適配器是這次對(duì)比的主角,適配器持有一個(gè)待適配的對(duì)象并且實(shí)現(xiàn)了目標(biāo)接口。通過(guò)使用適配器模式,可以大大提升程序的靈活性以及代碼的可重復(fù)性。

與之相對(duì),裝飾者實(shí)現(xiàn)待裝飾接口或繼承待裝飾類的同時(shí)持有一個(gè)待裝飾的實(shí)例,以此來(lái)為待裝飾類提供增強(qiáng)的功能。相較于繼承來(lái)說(shuō),裝飾模式更為靈活,但使用裝飾模式會(huì)產(chǎn)生比使用繼承關(guān)系更多的對(duì)象。更多的對(duì)象會(huì)使得查錯(cuò)變得困難,特別是這些對(duì)象看上去都很相像。
結(jié)構(gòu)上的不同在于從類圖中可以看出,裝飾模式持有和繼承的一般是同一個(gè)類或接口,而適配器持有的是待適配的對(duì)象,實(shí)現(xiàn)的是目標(biāo)接口。
功能上的不同在于裝飾模式中裝飾過(guò)的類力求與原來(lái)對(duì)外接口一致。這使得在調(diào)用方看來(lái),裝飾過(guò)后的類與之前沒(méi)有什么區(qū)別,只是某一方面功能增強(qiáng)了。但是適配器模式中適配器則擴(kuò)展了待適配類新的功能。簡(jiǎn)單來(lái)說(shuō),裝飾模式增強(qiáng)了原有功能,適配器模式拓展了新的功能。我們也可以看出,裝飾模式與適配器模式是不沖突的,可以既增強(qiáng)原有功能,又添加全新的功能。
裝飾模式VS代理模式
為什么拿出裝飾模式與代理模式再進(jìn)行對(duì)比?首先我們先看一下代理模式的類圖。

從類圖中可以看代理模式和裝飾模式是一致的。這里我要先說(shuō)明一下,有很多人執(zhí)著于代理模式的被代理對(duì)象是在代理對(duì)象的構(gòu)造函數(shù)中new出來(lái)的,而不是傳進(jìn)去的參數(shù),并且以此來(lái)區(qū)分裝飾模式和代理模式。我個(gè)人認(rèn)為這是有些偏頗的。比如對(duì)于動(dòng)態(tài)代理來(lái)說(shuō),被代理方肯定要作為參數(shù)傳入代理方中。
在我看來(lái)兩者的區(qū)別在于:代理模式中,代理方對(duì)被代理方有控制權(quán),對(duì)于調(diào)用方來(lái)說(shuō)兩者是分工十分清楚的兩個(gè)類,調(diào)用者很清楚它調(diào)用的是代理方。代理方的構(gòu)造函數(shù)可以有多個(gè)參數(shù),這使得它可以根據(jù)外界環(huán)境決定被代理方的運(yùn)行與否。裝飾模式中,裝飾者這是增強(qiáng)了被裝飾者的某種功能,對(duì)于調(diào)用方來(lái)說(shuō)兩者幾乎沒(méi)有區(qū)別。