介紹
結(jié)構(gòu)型設(shè)計(jì)模式之一,其使用一種對(duì)客戶端透明的方式來動(dòng)態(tài)擴(kuò)展對(duì)象的功能,同時(shí)它也是繼承關(guān)系的一種替代方案。
定義
動(dòng)態(tài)地給一個(gè)對(duì)象添加一些額外的職責(zé),就增加功能來說,裝飾模式相比生成子類更靈活。
使用場景
需要透明且動(dòng)態(tài)擴(kuò)展類的功能時(shí)。
類圖

裝飾器
舉個(gè)例子:
abstract class Shape{
abstract fun draw()
}
class Circle : Shape(){
override fun draw() {
println("draw a circle")
}
}
class Rectangle: Shape(){
override fun draw() {
println("draw a Rectangle")
}
}
open class Decorator(private val shape: Shape): Shape(){
override fun draw(){
shape.draw()
}
}
class BlueShape(shape: Shape): Decorator(shape){
override fun draw() {
println("蠟筆是藍(lán)色的了,可以畫畫了")
super.draw()
}
}
class BigShape(shape: Shape): Decorator(shape){
override fun draw() {
println("準(zhǔn)備畫一個(gè)大大的形狀")
super.draw()
}
}
fun main() {
//可以動(dòng)態(tài)任意的裝飾
val blueCircle = BlueShape(Circle())
blueCircle.draw()
println()
val bigRec = BigShape(Rectangle())
bigRec.draw()
println()
val bigBlueCircle = BigShape(BlueShape(Circle()))
bigBlueCircle.draw()
}
輸出:
蠟筆是藍(lán)色的了,可以畫畫了
draw a circle
準(zhǔn)備畫一個(gè)大大的形狀
draw a Rectangle
準(zhǔn)備畫一個(gè)大大的形狀
蠟筆是藍(lán)色的了,可以畫畫了
draw a circle
使用場景
這里使用 Java io 設(shè)計(jì)的庫作為基礎(chǔ)進(jìn)行 裝飾器模式的講解。

FilterInputStream 就是Decorator??梢越oInputStream動(dòng)態(tài)添加功能。FileInputStream 實(shí)現(xiàn)了從文件中獲取輸入流;DataInputStream實(shí)現(xiàn)了可以從輸入流中讀取java基礎(chǔ)類型數(shù)據(jù);BufferedInputStream實(shí)現(xiàn)了輸入流緩存的功能,ZipInputStream 實(shí)現(xiàn)了Zip輸入流的處理。 裝飾器衍生出來的類的目的是為了豐富基礎(chǔ)的輸入流,例如:
可以通過 DataInputStream 和 FileInputStream 組合一個(gè)從文件中讀取Java基礎(chǔ)數(shù)據(jù)類型的輸入流。,其實(shí)就是增強(qiáng)了FileInputStream(基于字節(jié)的輸入流)的功能,讓我們可以以Java基本數(shù)據(jù)類型去訪問輸入流。
DataInputStream input = new DataInputStream(new FileInputStream("a.txt"))
再比如,可以在剛才的基礎(chǔ)上,增加緩存功能。
DataInputStream input = new DataInputStream(new BufferedInputStream(new FileInputStream("a.txt")))