java设计模式初探之装饰者_JAVA设计模式初探之装饰者模式
裝飾者模式
1、意圖:?動態地給一個對象添加一些額外的職責。就增加功能來說, Decorator模式相比生成子類更為靈活。該模式以對客 戶端透明的方式擴展對象的功能。
2、適用環境
(1)在不影響其他對象的情況下,以動態、透明的方式給單個對象添加職責。
(2)處理那些可以撤消的職責。
(3)當不能采用生成子類的方法進行擴充時。一種情況是,可能有大量獨立的擴展,為支持每一種組合將產生大量的 子類,使得子類數目呈爆炸性增長。另一種情況可能是因為類定義被隱藏,或類定義不能用于生成子類。
3、參與者
1.Component(被裝飾對象的基類)
定義一個對象接口,可以給這些對象動態地添加職責。
2.ConcreteComponent(具體被裝飾對象)
定義一個對象,可以給這個對象添加一些職責。
3.Decorator(裝飾者抽象類)
維持一個指向Component實例的引用,并定義一個與Component接口一致的接口。
4.ConcreteDecorator(具體裝飾者)
具體的裝飾對象,給內部持有的具體被裝飾對象,增加具體的職責。
4、類圖
5、涉及角色
(1)抽象組件:定義一個抽象接口,來規范準備附加功能的類
(2)具體組件:將要被附加功能的類,實現抽象構件角色接口
(3)抽象裝飾者:持有對具體構件角色的引用并定義與抽象構件角色一致的接口
(4)具體裝飾:實現抽象裝飾者角色,負責對具體構件添加額外功能。
1 /定義被裝飾者2 public interfaceHuman {3 public voidwearClothes();4
5 public voidwalkToWhere();6 }7
8 //定義裝飾者
9 public abstract classDecorator implements Human {10 privateHuman human;11
12 publicDecorator(Human human) {13 this.human =human;14 }15
16 public voidwearClothes() {17 human.wearClothes();18 }19
20 public voidwalkToWhere() {21 human.walkToWhere();22 }23 }24
25 //下面定義三種裝飾,這是第一個,第二個第三個功能依次細化,即裝飾者的功能越來越多
26 public classDecorator_zero extends Decorator {27
28 publicDecorator_zero(Human human) {29 super(human);30 }31
32 public voidgoHome() {33 System.out.println("進房子。。");34 }35
36 public voidfindMap() {37 System.out.println("書房找找Map。。");38 }39
40 @Override41 public voidwearClothes() {42 //TODO Auto-generated method stub
43 super.wearClothes();44 goHome();45 }46
47 @Override48 public voidwalkToWhere() {49 //TODO Auto-generated method stub
50 super.walkToWhere();51 findMap();52 }53 }54
55 public classDecorator_first extends Decorator {56
57 publicDecorator_first(Human human) {58 super(human);59 }60
61 public voidgoClothespress() {62 System.out.println("去衣柜找找看。。");63 }64
65 public voidfindPlaceOnMap() {66 System.out.println("在Map上找找。。");67 }68
69 @Override70 public voidwearClothes() {71 //TODO Auto-generated method stub
72 super.wearClothes();73 goClothespress();74 }75
76 @Override77 public voidwalkToWhere() {78 //TODO Auto-generated method stub
79 super.walkToWhere();80 findPlaceOnMap();81 }82 }83
84 public classDecorator_two extends Decorator {85
86 publicDecorator_two(Human human) {87 super(human);88 }89
90 public voidfindClothes() {91 System.out.println("找到一件D&G。。");92 }93
94 public voidfindTheTarget() {95 System.out.println("在Map上找到神秘花園和城堡。。");96 }97
98 @Override99 public voidwearClothes() {100 //TODO Auto-generated method stub
101 super.wearClothes();102 findClothes();103 }104
105 @Override106 public voidwalkToWhere() {107 //TODO Auto-generated method stub
108 super.walkToWhere();109 findTheTarget();110 }111 }112
113 //定義被裝飾者,被裝飾者初始狀態有些自己的裝飾
114 public classPerson implements Human {115
116 @Override117 public voidwearClothes() {118 //TODO Auto-generated method stub
119 System.out.println("穿什么呢。。");120 }121
122 @Override123 public voidwalkToWhere() {124 //TODO Auto-generated method stub
125 System.out.println("去哪里呢。。");126 }127 }128 //測試類,看一下你就會發現,跟java的I/O操作有多么相似
129 public classTest {130 public static voidmain(String[] args) {131 Human person = newPerson();132 Decorator decorator = new Decorator_two(newDecorator_first(133 newDecorator_zero(person)));134 decorator.wearClothes();135 decorator.walkToWhere();136 }137 }
運行結果:
其實就是進房子找衣服,然后找地圖這樣一個過程,通過裝飾者的三層裝飾,把細節變得豐富。
關鍵點:
1、Decorator抽象類中,持有Human接口,方法全部委托給該接口調用,目的是交給該接口的實現類即子類進行調用。
2、Decorator抽象類的子類(具體裝飾者),里面都有一個構造方法調用super(human),這一句就體現了抽象類依賴于子類實現即抽象依賴于實現的原則。因為構造里面參數都是Human接口,只要是該Human的實現類都可以傳遞進去,即表現出Decorator dt = new Decorator_second(new Decorator_first(new Decorator_zero(human)));這種結構的樣子。所以當調用dt.wearClothes();dt.walkToWhere()的時候,又因為每個具體裝飾者類中,都先調用super.wearClothes和super.walkToWhere()方法,而該super已經由構造傳遞并指向了具體的某一個裝飾者類(這個可以根據需要調換順序),那么調用的即為裝飾類的方法,然后才調用自身的裝飾方法,即表現出一種裝飾、鏈式的類似于過濾的行為。
3、具體被裝飾者類,可以定義初始的狀態或者初始的自己的裝飾,后面的裝飾行為都在此基礎上一步一步進行點綴、裝飾。
4、裝飾者模式的設計原則為:對擴展開放、對修改關閉,這句話體現在我如果想擴展被裝飾者類的行為,無須修改裝飾者抽象類,只需繼承裝飾者抽象類,實現額外的一些裝飾或者叫行為即可對被裝飾者進行包裝。所以:擴展體現在繼承、修改體現在子類中,而不是具體的抽象類,這充分體現了依賴倒置原則,這是自己理解的裝飾者模式。
說的不清楚,有些只可意會不可言傳的感覺,多看幾遍代碼,然后自己敲出來運行一下,基本上就領悟了。
下面這個例子也有助于理解 裝飾的流程和作用
現在需要一個漢堡,主體是雞腿堡,可以選擇添加生菜、醬、辣椒等等許多其他的配料,這種情況下就可以使用裝飾者模式。
漢堡基類(被裝飾者,相當于上面的Human)
package decorator;
public abstract class Humburger {
protected String name ;
public String getName(){
return name;
}
public abstract double getPrice();
}
雞腿堡類(被裝飾者的初始狀態,有些自己的簡單裝飾,相當于上面的Person)
package decorator;
public class ChickenBurger extends Humburger {
public ChickenBurger(){
name = "雞腿堡";
}
@Override
public double getPrice() {
return 10;
}
}
配料的基類(裝飾者,用來對漢堡進行多層裝飾,每層裝飾增加一些配料,相當于上面Decorator)
package decorator;
public abstract class Condiment extends Humburger {
public abstract String getName();
}
生菜(裝飾者的第一層,相當于上面的decorator_zero)
package decorator;
public class Lettuce extends Condiment {
Humburger humburger;
public Lettuce(Humburger humburger){
this.humburger = humburger;
}
@Override
public String getName() {
return humburger.getName()+" 加生菜";
}
@Override
public double getPrice() {
return humburger.getPrice()+1.5;
}
}
辣椒(裝飾者的第二層,相當于上面的decorator_first)
package decorator;
public class Chilli extends Condiment {
Humburger humburger;
public Chilli(Humburger humburger){
this.humburger = humburger;
}
@Override
public String getName() {
return humburger.getName()+" 加辣椒";
}
@Override
public double getPrice() {
return humburger.getPrice(); //辣椒是免費的哦
}
}
測試類
package decorator;
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
Humburger humburger = new ChickenBurger();
System.out.println(humburger.getName()+" 價錢:"+humburger.getPrice());
Lettuce lettuce = new Lettuce(humburger);
System.out.println(lettuce.getName()+" 價錢:"+lettuce.getPrice());
Chilli chilli = new Chilli(humburger);
System.out.println(chilli.getName()+" 價錢:"+chilli.getPrice());
Chilli chilli2 = new Chilli(lettuce);
System.out.println(chilli2.getName()+" 價錢:"+chilli2.getPrice());
}
}
輸出
雞腿堡 價錢:10.0
雞腿堡 加生菜 價錢:11.5
雞腿堡 加辣椒 價錢:10.0
雞腿堡 加生菜 加辣椒 價錢:11.5
作者:jason0539
總結
以上是生活随笔為你收集整理的java设计模式初探之装饰者_JAVA设计模式初探之装饰者模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python迭代器举例_如何最简单、通俗
- 下一篇: netpref 使用_使用PerfVie