装饰者设计模式
裝飾者設(shè)計模式
- 什么是裝飾者設(shè)計模式
- 實戰(zhàn)
什么是裝飾者設(shè)計模式
裝飾者設(shè)計模式(Decorator Pattern)將某個方法進(jìn)行增強(qiáng),可以在被裝飾的方法執(zhí)行前后加上想要的邏輯處理進(jìn)行增強(qiáng),又可以不改變現(xiàn)有的結(jié)構(gòu)。這種模式創(chuàng)建了一個裝飾類,用來包裝原有的類,并在保持類方法簽名完整性的前提下,提供額外的功能。
使用場景: 1、擴(kuò)展一個類的功能。 2、動態(tài)增加功能,動態(tài)撤銷。
注意事項:可代替繼承
實戰(zhàn)
我們利用女孩化妝來演示裝飾者設(shè)計模式,首先我們定義一個接口,擁有展示的行為:
public interface Showable {void show(); }當(dāng)然女友會這門功夫了,所以實現(xiàn)了此行為并施展其“美麗的臉龐”了,但此時只是原生態(tài)的素顏。
public class Girl implements Showable {@Overridepublic void show() {System.out.print("女孩的素顏");} }沒什么復(fù)雜的,直接調(diào)用的話會是素面朝天直面慘淡的人生,這樣當(dāng)然達(dá)不到美顏效果了,何以一顧傾城。那么接下來要進(jìn)行化妝了,這里必須依靠一種神秘而又昂貴的東西,化妝品登場了,它同樣實現(xiàn)了Showable接口。
public class Decorator implements Showable {/*** 擁有某個善于展示的對象*/private Showable showable;public Decorator(Showable showable){this.showable = showable;}@Overridepublic void show() {System.out.print("化妝(");showable.show();System.out.println(")");} }我們可以發(fā)現(xiàn),在構(gòu)造化妝品類的時候可以把女孩給注入進(jìn)來,目的在于調(diào)用女孩的show方法,但對于其原本的具體行為裝飾器一無所知,并且沒有加入任何邏輯限制,它所做的無非是“畫龍點睛”,“錦上添花”。接下來我們來運行一下看結(jié)果:
public class TestShowable {public static void main(String[] args) {//將需要被加強(qiáng)的對象傳遞給裝飾類new Decorator(new Girl()).show();//結(jié)果:打扮(女孩的素顏)} }我們可以看到,只需要新建裝飾器的時候把女孩給包裝進(jìn)去就得到了粉飾過的美顏,是不是非常簡單?然而此時有女朋友會嫌棄了,“只是打粉底這么簡單嗎?眼霜呢?口紅呢……”。
好吧,為了滿足女友的要求,我們得再多一些設(shè)計。想想看這些化妝品,不管是什么都有共同的特性,也就是說他們統(tǒng)統(tǒng)都可以裝飾原生態(tài)的素顏展示方法show,那我們何不把這些特性抽象出來呢?開始行動,修改我們的裝飾類
public abstract class Decorator implements Showable {/*** 擁有某個善于展示的對象*/protected Showable showable;public Decorator(Showable showable){this.showable = showable;}public void show() {//直接調(diào)用,不加任何裝飾showable.show();} }我們把化妝品類給改成抽象類,重寫show方法,但不做任何粉飾了,這里我們留給子類具體的某個化妝品去做裝飾吧。化妝首先第一步一定要打底了,這里我們首先加入一個口紅類:
public class Lipstick extends Decorator{public Lipstick(Showable showable) {//調(diào)用父類構(gòu)造賦值給成員屬性super(showable);}@Overridepublic void show() {System.out.print("涂口紅(");showable.show();System.out.print(")");} }涂完口紅,最后再噴點香水吧。同樣的,我們再定義一個香水類:
public class Perfume extends Decorator {public Perfume(Showable showable) {super(showable);}@Overridepublic void show() {System.out.println("噴香水(");showable.show();System.out.println(")");} }最后,我們把女友、口紅、香水層層包裹起來并運行,結(jié)果如愿以償。
public class TestShowable {public static void main(String[] args) {//將需要被加強(qiáng)的對象傳遞給裝飾類,層層包裹起來,每一層都多了一些功能new Perfume(new Lipstick(new Girl())).show();//結(jié)果: 噴香水(涂口紅(女孩的素顏))} }如果女友對這種淡妝效果還是不滿意,我們可以繼續(xù)添加化妝品類,睫毛膏、眼線、眉筆、腮紅等等等等,只需要層層包裹起來,最終實現(xiàn)女友濃妝艷抹的夢想。
我們觀察這種裝飾器模式結(jié)構(gòu),是不是似曾相識呢?沒錯,其實裝飾器模式在JDK里就有很多應(yīng)用,比如Java IO包里的眾多流處理類。
new BufferedReader(new InputStreamReader(new FileInputStream(filePath)));當(dāng)然,流處理類當(dāng)然要比我們的例子復(fù)雜的多,但其基本思想和我們?nèi)シ本秃喌睦赢愅就瑲w,這些對象就好像是俄羅斯套娃一樣層層包裹,層層裝飾,每套一層就會多出一些功能出來,我們更可以自由搭配,實現(xiàn)不同的組合功能。
總結(jié)
- 上一篇: Web服务必须要知道的几个概念
- 下一篇: 开发中最常使用到那些设计模式?