裝飾者模式

一、定義

    動態添加對象功能。通過委託機制,複用系統中的各個組件,在運行時,可以講這些功能組件進行疊加,從而組成一個“超級對象”。

二、設計思想

    代碼複用應該儘可能使用組合(委託),而不是使用繼承。因爲繼承是一種緊密耦合,任何父類的改動都會影響到子類,不利於系統維護。裝飾者模式可以有效的分離性能組件和功能組件,從而有效提升模塊的可維護性和複用性。

三、四個角色

(1)組件接口

    組件接口是裝飾者和被裝飾者的超類或者公共接口。它定義了被裝飾者的核心功能和裝飾者需要加強的功能點。

(2)具體組件

    具體組件實現了組件接口的核心方法,完成一個核心的功能。而其他性能方面或者額外的功能方面,交由裝飾者去實現。

(3)裝飾者

    實現組件接口的一個類,並且持有一個組件(即被裝飾者)對象。

(4)具體裝飾者

    實現了抽象的裝飾者,完成具體的裝飾邏輯,實現性能的增強。各個具體裝飾者可以疊加,從而構成一個功能更強大的組件對象。

四、代碼實現

IBuilding.java       具體組件和裝飾者的公共接口,從而保證被裝飾者和裝飾者具有相同的接口
public interface IBuilding {
	public String getDetails();
}
Building.java
public class Building implements IBuilding{

	public String getDetails() {
		// TODO Auto-generated method stub
		return "一間普通的房子";
	}
}
BuildingDecorator.java       裝飾者的抽象類,持有一個被裝飾對象
public abstract class BuildingDecorator implements IBuilding{
	IBuilding building;
	public  BuildingDecorator(IBuilding building) {
		this.building=building;
	}

}
LightingDecorator.java    燈飾裝飾
public class LightingDecorator extends BuildingDecorator {

	public LightingDecorator(IBuilding building) {
		super(building);
	}

	public String getDetails() {
		// TODO Auto-generated method stub
		StringBuffer sb=new StringBuffer();
		sb.append(building.getDetails());
		sb.append(",裝上燈飾");
		return sb.toString();
	}
}
FlowerDecorator.java   鮮花裝飾
public class FlowerDecorator extends BuildingDecorator {

	public FlowerDecorator(IBuilding building) {
		super(building);
	}

	public String getDetails() {
		// TODO Auto-generated method stub
		StringBuffer sb=new StringBuffer();
		sb.append(building.getDetails());
		sb.append(",放上幾盆花");
		return sb.toString();
	}
}

LearnDecorator.java
public class LearnDecorator {
	public static void main(String[] args) {
		//通過層層構造,將裝飾者添加到被裝飾對象上,可以有選擇性的添加裝飾者
		IBuilding building=new LightingDecorator(new FlowerDecorator(new Building()));
		System.out.println(building.getDetails());
	}
}
運行結果:
一間普通的房子,放上幾盆花,裝上燈飾


五、裝飾者模式的具體應用場景

    在JDK的實現中,有不少組件使用了裝飾者模式。最典型的一個例子就是I/O。下面以OutputStream爲例。
(1)組件接口:OutputStream
(2)具體組件:FileOutputStream
(3)裝飾者:FilterOutputStream
(4)第一個具體的裝飾者:BufferedOutputStream   可以對FileOutputStream增加緩衝功能,優化IO性能。
(5)第二個具體的裝飾者:DataOutputStream      增加了對多種類型數據的寫操作支持。

		DataOutputStream outputStream=new DataOutputStream(new BufferedOutputStream(new FileOutputStream("f:/example.txt")));
		outputStream.writeChars("hello world");






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章