android設計模式二十三式(七)——裝飾器模式(Decorator)

裝飾器模式

所謂的裝飾器,字面上的意思,就是對某個東西進行裝飾,在原始的基礎上,再添加上一些其他的功能,讓整個效果更佳完善。所以,這裏就有一個而基礎功能,還有就是裝飾功能。裝飾模式的特點就是,裝飾器和被裝飾者都實現了同一個接口,裝飾器中有被裝飾者。

我們依舊來個小場景。假設我們有一個女朋友,今天你要帶她出席一個很盛大的晚宴,所以她平時只會用水洗個頭發,今天就得用上洗髮液,護髮素,彈力膠,最後還要造個型。

/**
 * @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、動態的爲一個對象增加功能,而且還能動態撤銷。(繼承不能做到這一點,繼承的功能是靜態的,不能動態增刪。)

缺點:

產生過多相似的對象,不易排錯!

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