裝飾模式職責
動態的爲一個對象增加新的功能。
裝飾模式是一種用於代替繼承的技術,無需通過繼承增加子類就能擴展對象的新功能。使用對象的關聯關係代替繼承關係,更加靈活,同時避免類型體系的快速膨脹。
實現細節
Component抽象構件角色:真實對象和裝飾對象有相同的接口。這樣,客戶端對象就能夠以與真實對象相同的方式同裝飾對象交互。
Concrete Component具體構件角色(真實對象):例如io流中的FileInputStream、FlieOutputStream
Decorator裝飾角色:持有一個抽象構件的引用。裝飾對象接受所有客戶端的請求,並把這些請求轉發給真實的對象。這樣,就能在真實對象調用前後增加新的功能。
Concrete Decorator具體裝飾角色:負責給結構對象增加新的責任。
裝飾模式demo
建立抽象組件ICar,具體構建角色(真實對象)Car,裝飾角色SuperCar,具體裝飾對象WaterCar,FlyCar,AICar都繼承了SuperCar。在真正構建Car對象的時候,組裝方式靈活多樣。
public interface ICar {
void move();
}
public class Car implements ICar{
@Override
public void move() {
System.out.println("陸地上跑!");
}
}
public class SuperCar extends Car implements ICar{
protected ICar car;
public SuperCar(ICar car) {
this.car = car;
}
@Override
public void move() {
car.move();
}
}
public class WaterCar extends SuperCar {
public WaterCar(ICar car) {
super(car);
}
public void swim(){
System.out.println("水裏遊!");
}
@Override
public void move() {
super.move();
swim();
}
}
public class FlyCar extends SuperCar {
public FlyCar(ICar car) {
super(car);
}
public void fly(){
System.out.println("天上飛!");
}
@Override
public void move() {
super.move();
fly();
}
}
public class AICar extends SuperCar {
public AICar(ICar car) {
super(car);
}
public void autoMove(){
System.out.println("陸地自動駕駛!");
}
@Override
public void move() {
super.move();
autoMove();
}
}
public class Client {
public static void main(String[] args) {
Car car = new Car();
car.move();
System.out.println("增加新的功能,飛行-----------");
FlyCar flyCar = new FlyCar(car);
flyCar.move();
System.out.println("增加新的功能,水裏遊-----------");
WaterCar waterCar = new WaterCar(car);
waterCar.move();
System.out.println("增加新的功能,飛行+陸地自動駕駛-----------");
AICar aiCar = new AICar(flyCar);
aiCar.move();
System.out.println("增加新的功能,飛行+水裏遊+陸地自動駕駛-----------");
AICar aiCar2 = new AICar(new FlyCar(car));
aiCar2.move();
}
}
結果如下所示:
裝飾模式類圖
開發中應用的場景
IO中輸入流和輸出流的設計
Swing包中圖形界面構件功能
Servlet API中提供了一個request對象的Decorator設計模式的默認實現類HttpServletRequestWapper,HttpServletRequestWapper類增強了request對象的功能。
Struts2中,request、response、session對象的處理
IO流實現細節
Component抽象構建角色:io流中的InputStream、OutputStream、Reader、Writer
ConcreteComponent具體構建角色:io流中的FileInputStream、FileOutputStream
Decorator裝飾角色:持有一個抽象構件的引用:io流中的FilterInputStream、FilterOutputStream
Concrete Decorator具體裝飾角色:負責給構件對象增加新的責任。io流中的BufferedOutputStream、BufferedInputStream等
總結
裝飾模式(Decorator)也叫包裝器模式(Wrapper)。
裝飾模式降低系統的耦合度,可以動態的增加或者刪除對象的職責,並使得需要裝飾的具體構件類和具體裝飾類可以獨立變化,以使增加新的具體構件類和具體裝飾類。
優點:擴展對象功能,比繼承靈活,不會導致類個數急劇增加;可以對一個對象進行多次裝飾,創造出不同行爲的組合,得到功能更加強大的對象;具體構件類和具體裝飾類可以獨立變化,用戶可以根據需要自己增加新的具體構件子類和具體裝飾子類。
缺點:產生很多小對象。大量小對象佔據內存,一定程度上影響性能;裝飾模式易於出錯,調試排查比較麻煩。
裝飾模式和橋接模式的區別:兩個模式都是爲了解決過多子類對象問題,但他們的誘因不一樣。橋接模式是對象自身現有機制沿着多個維度變化,是既有部分不穩定。裝飾模式是爲了增加新的功能。
以上爲裝飾模式的學習筆記,此文章爲尚學堂視頻的學習筆記+自己總結。