裝飾器模式
所謂的裝飾器,字面上的意思,就是對某個東西進行裝飾,在原始的基礎上,再添加上一些其他的功能,讓整個效果更佳完善。所以,這裏就有一個而基礎功能,還有就是裝飾功能。裝飾模式的特點就是,裝飾器和被裝飾者都實現了同一個接口,裝飾器中有被裝飾者。
我們依舊來個小場景。假設我們有一個女朋友,今天你要帶她出席一個很盛大的晚宴,所以她平時只會用水洗個頭發,今天就得用上洗髮液,護髮素,彈力膠,最後還要造個型。
/**
* @author: hx
* @Time: 2019/5/8
* @Description: GirlFriend
*/
public interface GirlFriend {
/**
* 所有的女朋友都會洗頭髮
*/
void washHair();
}
/**
* @author: hx
* @Time: 2019/5/8
* @Description: MyGirlFriend
*/
public class MyGirlFriend implements GirlFriend {
@Override
public void washHair() {
System.out.println("用水洗頭髮");
}
}
/**
* @author: hx
* @Time: 2019/5/8
* @Description: Decorator 裝飾器
* 專門用來做頭髮的,來裝飾一下我們的女朋友
* 實現女朋友接口,所有的女朋友都會洗頭嘛,就是洗頭髮要升級一下。
*/
public class Decorator implements GirlFriend {
/**
* 內部持有一個我們自己的女朋友
*/
private GirlFriend mGirlFriend;
public Decorator(GirlFriend girlFriend) {
super();
mGirlFriend = girlFriend;
}
@Override
public void washHair() {
System.out.println("加上洗髮液");
mGirlFriend.washHair();
System.out.println("加上護髮素");
mGirlFriend.washHair();
System.out.println("上彈力膠");
System.out.println("造型");
}
}
來用一下這個裝飾頭髮的新機器
public static void main(String[] args){
GirlFriend girlFriend = new MyGirlFriend();
Decorator decorator = new Decorator(girlFriend);
decorator.washHair();
}
輸出結果:
加上洗髮液
用水洗頭髮
加上護髮素
用水洗頭髮
上彈力膠
造型
我們看一下Decorator這個類,是不是很像對象的適配器模型,內部持有一個對象,將對象的進行處理,只不過我們沒有對輸出的接口做相應的規定。
裝飾模式,在android的java.io中,使用的非常非常廣泛,看一下源碼
new BufferedOutputStream(new FileOutputStream()));
public class DataOutputStream extends FilterOutputStream implements DataOutput {
/**
* Creates a new data output stream to write data to the specified
* underlying output stream. The counter <code>written</code> is
* set to zero.
*
* @param out the underlying output stream, to be saved for later
* use.
* @see java.io.FilterOutputStream#out
*/
public DataOutputStream(OutputStream out) {
super(out);
}
/**
* Writes a <code>long</code> to the underlying output stream as eight
* bytes, high byte first. In no exception is thrown, the counter
* <code>written</code> is incremented by <code>8</code>.
*
* @param v a <code>long</code> to be written.
* @exception IOException if an I/O error occurs.
* @see java.io.FilterOutputStream#out
*/
public final void writeLong(long v) throws IOException {
writeBuffer[0] = (byte)(v >>> 56);
writeBuffer[1] = (byte)(v >>> 48);
writeBuffer[2] = (byte)(v >>> 40);
writeBuffer[3] = (byte)(v >>> 32);
writeBuffer[4] = (byte)(v >>> 24);
writeBuffer[5] = (byte)(v >>> 16);
writeBuffer[6] = (byte)(v >>> 8);
writeBuffer[7] = (byte)(v >>> 0);
out.write(writeBuffer, 0, 8);
incCount(8);
}
}
public class FilterOutputStream extends OutputStream {
/**
* The underlying output stream to be filtered.
*/
protected OutputStream out;
/**
* Creates an output stream filter built on top of the specified
* underlying output stream.
*
* @param out the underlying output stream to be assigned to
* the field <tt>this.out</tt> for later use, or
* <code>null</code> if this instance is to be
* created without an underlying stream.
*/
public FilterOutputStream(OutputStream out) {
this.out = out;
}
}
裝飾器模式的應用場景:
1、需要擴展一個類的功能。
2、動態的爲一個對象增加功能,而且還能動態撤銷。(繼承不能做到這一點,繼承的功能是靜態的,不能動態增刪。)
缺點:
產生過多相似的對象,不易排錯!