https://www.bilibili.com/video/av29579073/?p=16
今天這篇博客我來說一下裝飾器模式。
裝飾器模式(Decorator Pattern)允許向一個現有的對象添加新的功能,同時又不改變其結構。這種類型的設計模式屬於結構型模式,它是作爲現有的類的一個包裝。裝飾器模式相比生成子類會更加靈活。
裝飾器模式由於較爲複雜,涉及到的類也是比較多的。總體分爲四個部分
– Component抽象構件角色: • 真實對象和裝飾對象有相同的接口。這樣,客戶端對象就能夠以與真實對象相同的方式同裝飾 對象交互。這是一個最基本的接口,聲明瞭一個類組所具有的全部的功能。
– ConcreteComponent 具體構件角色(真實對象): • io流中的FileInputStream、FileOutputStream。這個類是對於Component接口的繼承,實現了一些較爲基礎的方法。
以上兩個部分都是基礎部分的構建,下面是關於裝飾器部分的說明。
– Decorator裝飾角色: • 持有一個抽象構件的引用。裝飾對象接受所有客戶端的請求,並把這些請求轉發給真實的對象 。這樣,就能在真實對象調用前後增加新的功能。這個類可以看到是負責處理用戶請求的,它包含了一個ConcreteComponent 對象的引用並同時實現了Component構件聲明的方法
– ConcreteDecorator具體裝飾角色: • 負責給構件對象增加新的責任。它也是繼承了Decorator這個抽象類的同時實現Component構件聲明的方法,在對應的方法中實現了ConcreteComponent 構件已有的方法和自己新添加的,也就是裝飾方法的說明。
裝飾器模式運用最多的就是關於java自帶的IO流的處理。視頻也是模仿IO的實現方式實現了一個小車的功能實現模擬。
首先是抽象構件部分,也就是Component部分
public interface ICar {
void move();
}
其次是對於這個類的一些基本方法的實現
//ConcreteComponent 具體構件角色(真實對象)
class Car implements ICar {
@Override
public void move() {
System.out.println("陸地上跑!");
}
}
接下來是裝飾器基類的聲明
//Decorator裝飾角色
class SuperCar implements ICar {
protected ICar car;
public SuperCar(ICar car) {
super();
this.car = car;
}
@Override
public void move() {
car.move();
}
}
可以看到這個類持有一個Component接口的引用並且重寫了相應的move()方法。接下來就是裝飾器類具體的擴展,也就是對於Component組件功能的擴展說明。
//ConcreteDecorator具體裝飾角色
class FlyCar extends SuperCar {
public FlyCar(ICar car) {
super(car);
}
public void fly(){
System.out.println("天上飛!");
}
@Override
public void move() {
super.move();
fly();
}
}
//ConcreteDecorator具體裝飾角色
class WaterCar extends SuperCar {
public WaterCar(ICar car) {
super(car);
}
public void swim(){
System.out.println("水上游!");
}
@Override
public void move() {
super.move();
swim();
}
}
//ConcreteDecorator具體裝飾角色
class AICar extends SuperCar {
public AICar(ICar car) {
super(car);
}
public void autoMove(){
System.out.println("自動跑!");
}
@Override
public void move() {
super.move();
autoMove();
}
}
這幾個類都是繼承了SuperCar同時具有一個ICar的引用,實現了不同功能的小車的組合。下面來看測試類。
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("增加兩個新的功能,飛行,水裏遊-------");
WaterCar waterCar2 = new WaterCar(new FlyCar(car));
waterCar2.move();
// Reader r = new BufferedReader(new InputStreamReader(new FileInputStream(new File("d:/a.txt"))));
}
}
這個測試列也是可以看出,基本功能的對象引用作爲屬性注入到相應的裝飾器類的構造方法中,爲我們的基本類實現了功能的擴展。