裝飾模式
裝飾模式定義
定義:裝飾模式就是動態(tài)的得給一個對象添加一些額外的職責(zé),就增加功能來說,裝飾器模式比生成子類更為靈活;
裝飾模式結(jié)構(gòu)圖:
"Component是定義一個對象接口,可以給這些對象動態(tài)的添加職責(zé);ConcreteComponent是定義了一個具體的對象,也可以給這個對象添加一些職責(zé).Decorator,裝飾抽象類,繼承了component從外類來拓展Component類的功能,但對于Component來說,是無需知道Decorator的存在.至于ConcreteDecorator就是具體的裝飾對象,起到給Component添加職責(zé)的功能"
裝飾模式是利用setComponent來對對象進行包裝的.這樣每個裝飾對象的實現(xiàn)就和如何使用這個對象分離開了,每個裝飾對象只關(guān)心自己的功能,不需要關(guān)心如何被添加到對象鏈當(dāng)中
裝飾器模式的實現(xiàn)
1.新建一個ConcreteComponent人類,其中提供構(gòu)造方法和show方法
package org.example.component;
/**
* @author
* @date 2021/3/9 15:20
**/
public class Person {
private String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
public void show() {
System.out.println("裝扮的" + name);
}
}
2.編寫裝飾抽象類并繼承于人類,實現(xiàn)其show方法,并提供Person屬性
package org.example.component;
/**
* @author
* @date 2021/3/9 15:21
**/
public class Finery extends Person {
protected Person person;
public void Decorate(Person person) {
System.out.println("person");
this.person = person;
}
@Override
public void show() {
if (person != null) {
person.show();
}
}
}
3.編寫具體裝扮類
public class BigTrouser extends Finery {
@Override
public void show() {
System.out.println("垮褲");
super.show();
}
}
public class Shoes extends Finery{
@Override
public void show() {
System.out.println("鞋子");
super.show();
}
}
public class Tshirts extends Finery{
@Override
public void show() {
System.out.println("大T");
super.show();
}
}
4.客戶端調(diào)用
package org.example.component;
/**
* @author
* @date 2021/3/9 15:28
**/
public class Test3 {
public static void main(String[] args) {
Person test = new Person("測試");
Tshirts tshirts = new Tshirts();
BigTrouser bigTrouser = new BigTrouser();
Shoes shoes = new Shoes();
//添加到對象鏈中
tshirts.Decorate(test);
bigTrouser.Decorate(tshirts);
shoes.Decorate(bigTrouser);
shoes.show();
}
}
5.運行結(jié)果
裝飾器模式調(diào)用流程
裝飾器模式的優(yōu)缺點
優(yōu)點
裝飾類和被裝飾類可以獨立發(fā)展跪削,而不會相互耦合夺巩。換句話說,Component類無需知道Decorator類舀奶,Decorator類是從外部來擴展Component類的功能瞧捌,而Decorator也不用知道具體的構(gòu)件。
裝飾器模式是繼承關(guān)系的一個替代方案。我們看裝飾類Decorator页慷,不管裝飾多少層,返回的對象還是Component(因為Decorator本身就是繼承自Component的)胁附,實現(xiàn)的還是is-a的關(guān)系酒繁。
-
裝飾模式可以動態(tài)地擴展一個實現(xiàn)類的功能,比如在I/O系統(tǒng)中控妻,我們直接給BufferedInputStream的構(gòu)造器直接傳一個InputStream就可以輕松構(gòu)件一個帶緩沖的輸入流州袒,如果需要擴展,我們繼續(xù)“裝飾”即可弓候。
缺點
多層的裝飾是比較復(fù)雜的郎哭。為什么會復(fù)雜?你想想看菇存,就像剝洋蔥一樣夸研,你剝到最后才發(fā)現(xiàn)是最里層的裝飾出現(xiàn)了問題,可以想象一下工作量依鸥。這點從我使用Java I/O的類庫就深有感受亥至,我只需要單一結(jié)果的流,結(jié)果卻往往需要創(chuàng)建多個對象,一層套一層姐扮,對于初學(xué)者來說容易讓人迷惑絮供。