前言:
來源於《head first 設計模式》。當作讀書筆記了,這次看的是第三章裝飾者模式。看得有點上癮。。。抽出了點時間來總結一下。
裝飾者模式的概念
動態地將責任附加到對象之上。想要擴展功能,裝飾者提供有別於繼承的另一種選擇。
head fitst基本操作舉個例子
head first裏面舉了兩個例子,一個是星巴克一個我們熟悉的java i/o包。這裏爲了方便就用java i/o來展示我們的裝飾者模式吧。
通用的觀察者模式的uml圖
慣例貼一下uml圖,這是通用的觀察者模式的uml圖,我們看完它再來了解java i/o的會更好理解
Component:作用是規定了同一個父類,讓每一個組件都可以單獨使用或者被裝飾者包含起來。
ConcreteComponent:這是我們要動態地加上新行爲的對象,繼承與Component.
Decorator:這是裝飾者共同需要實現的接口或者繼承的父類,它使每個裝飾者都帶有一個或者說是包含一個組件,即有一個實例變量來保存某一Component
ConcreteDecoraror:裝飾者咯,可以拓展新的方法或者增加新的行爲在舊的行爲後面
Java i/o的uml:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-1h1B6wlP-1586688264037)(https://imgblog.csdnimg.cn/20200412183344793.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2F3YWtlX2xxaA==,size_16,color_FFFFFF,t_70)]
並沒有把所有的類都寫出了,寫了幾個點名關係即可了。
InputStream:相當於上方的component
FileInputStream:相當於被修飾的對象
StringBufferInputStream:相當於被修飾的對象
FilterInputStream:修飾者共同的父類了,裏面包含了一個inputstream實例。
LowerCaseInputStream代碼:
public class LowerCaseInputStream extends FilterInputStream {
protected LowerCaseInputStream(InputStream in) {
super(in);
}
//針對字節流
public int read() throws IOException{
int c=super.read();
return (c==-1?c:Character.toLowerCase(((char)c)));
}
//針對字節數組
public int read(byte[] b,int offset,int len) throws IOException {
int result=super.read(b,offset,len);
for (int i=offset;i<offset+result;i++){
b[i]= (byte) Character.toLowerCase(((char)b[i]));
}
return result;
}
}
測試代碼:
public class InputTest {
public static void main(String[] args) {
int c;
try {
InputStream in=new LowerCaseInputStream(
new BufferedInputStream(
new FileInputStream("./test.txt")));
while ((c=in.read())>=0){
System.out.print((char)c);
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
總結:
InputStream in=new LowerCaseInputStream(
new BufferedInputStream(
new FileInputStream("./test.txt")));
這是平常我們書寫一個讀取類基本的寫法把,類似於套娃。我們可以理解爲我們先用BufferedInputStream修飾了組件FileInputStream,再用我們自己的LowerCaseInputStream修飾了BufferedInputStream。read的方法的調用就先調用FileInputStream從文件中讀取然後到BufferedInputStream用字符流再到LowerCaseInputStream轉化爲小寫,這樣統分體現了裝飾者模式對方法的擴展,又不會影響上層代碼,同時對於java i/o這種類別特別多已經功能又重複,或者再某個類基礎上加強的,最爲適用。
裝飾者模式簡單來講其實就是:動態的給一個對象添加一些額外的功能,而無需修改上層代碼。