先整理下裝飾者模式的基本概念:
裝飾模式(Decorator)的定義:又名包裝(Wrapper)模式,裝飾模式以對客戶端透明的方式擴展對象的功能,是繼承關係的一個替代方案。
裝飾模式以對客戶端透明的方式動態的給一個對象附加上更多的責任。換言之客戶端並不會覺的對象在裝飾前和裝飾後有什麼區別。
裝飾模式可以在不創造更多的子類的模式下,將對象的功能加以擴展。
代碼整理如下:
(經典的coffee加料例子)
抽象被繼承者類:Beverage.java
[java] view plaincopy
package com.designpattern.decorator;
//被裝飾者抽象類
public abstract class Beverage {
String description = “Unknown Beverage”;
public String getDescription(){
return description;
}
public abstract double cost();
}
具體被裝飾類:HouseBlend.java, DarkRoast.java, Decat.java, Espresso.java,只給出一個,其他類似
[java] view plaincopy
package com.designpattern.decorator;
//被裝飾者具體類
public class HouseBlend extends Beverage{
public HouseBlend(){
description = "House Blend Coffee";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 0.89;
}
}
裝飾者抽象類:CondimentDecorator.java
[java] view plaincopy
package com.designpattern.decorator;
//裝飾者抽象類
public abstract class CondimentDecorator extends Beverage{
public abstract String getDescription();
}
具體裝飾者類:Mocha.java,Soy.java,Milk.java,Whip.java,只給出一個,其他類似
[java] view plaincopy
package com.designpattern.decorator;
//裝飾者的具體類
public class Mocha extends CondimentDecorator{
Beverage beverage;
public Mocha(Beverage beverage){
this.beverage = beverage;
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return beverage.getDescription() + ", Mocha";
}
@Override
public double cost() {
// TODO Auto-generated method stub
return 0.20 + beverage.cost();
}
}
測試類:Test.java
[java] view plaincopy
package com.designpattern.decorator;
public class Test {
public static void main(String[] args) {
//不需要調料,即沒有裝飾者
Beverage beverage1 = new Espresso();
System.out.println(beverage1.getDescription() + ” $” + beverage1.cost());
//使用了三個裝飾者來裝飾DarkRoast
Beverage beverage2 = new DarkRoast();
beverage2 = new Mocha(beverage2);
beverage2 = new Soy(beverage2);
beverage2 = new Whip(beverage2);
System.out.println(beverage2.getDescription() + " $" + beverage2.cost());
//使用了兩個裝飾者來裝飾HouseBlend
Beverage beverage3 = new HouseBlend();
beverage3 = new Mocha(beverage3);
beverage3 = new Soy(beverage3);
System.out.println(beverage3.getDescription() + " $" + beverage3.cost());
}
}
** 要點總結
1)繼承屬於擴展形式之一,但不見得是達到彈性設計的最佳方式。
2)在設計中,應該允許行爲可以被擴展,而無須修改現有的代碼。
3)組合和委託可用於在運行時動態地加上新的行爲。
4)除了繼承,裝飾者模式也可以讓我們擴展行爲。
5)裝飾者模式意味着一羣裝飾者類,這些類用來包裝具體組件。
6)裝飾者類反映出被裝飾的組件類型(事實上,他們具有相同的類型,都經過接口或繼承實現)。
7)裝飾者可以在被裝飾者的行爲前面與/或後面加上自己的行爲,甚至將被裝飾者的行爲整個取代掉,而達到特定的目的。
8)可以用無數個裝飾者包裝一個組件。
9)裝飾者一般對組件的客戶是透明的,除非客戶程序依賴於組件的具體類型。
10)裝飾者會導致設計中出現許多小對象,如果過度使用,會讓程序變得很複雜。**