允許動態的向一個現有對象增加新功能,同時又不改變它的結構,相當於對現有對象的一個包裝,因此裝飾器模式也被稱作包裝模式。
裝飾器模式中一般存在以下四中角色
- 抽象組件:具體組件和抽象裝飾器共同的父類,最基礎的組件
- 具體組件:實現抽象構建中聲明的方法,裝飾器可以給它增加額外的職責
- 抽象裝飾器:繼承抽象組件並且可以通過構造方法引入具體組件,它的作用主要是組合具體組件
- 具體裝飾器:繼承抽象裝飾器,給組件做不同的裝飾。
下面使用一個裝飾汽車的實例來實現一下裝飾器模式
public interface Car {
/**
* 汽車描述
*/
void describe();
}
汽車下面有兩個具體的實現類,分別代表燃油車和新能源車
public class EnergyCar implements Car{
@Override
public void describe() {
System.out.print("新能源汽車");
}
}
public class FuelCar implements Car{
@Override
public void describe() {
System.out.printf("燃油車");
}
}
汽車顏色裝飾的抽象類
public class CarColorDecorator implements Car{
private final Car car;
public CarColorDecorator(Car car) {
this.car = car;
}
@Override
public void describe(){
car.describe();
}
}
具體汽車顏色的抽象類,再這裏面可以組合相應的組件
public class CarColorDecorator implements Car{
private final Car car;
public CarColorDecorator(Car car) {
this.car = car;
}
@Override
public void describe(){
car.describe();
}
}
具體汽車顏色的實現類,對相應的方法進行修飾增加功能
public class CarRedColorDecorator extends CarColorDecorator{
public CarRedColorDecorator(Car car) {
super(car);
}
@Override
public void describe() {
System.out.printf("紅色的");
super.describe();
}
}
測試
public class DecoratorTest {
@Test
public void test(){
Car car = new CarRedColorDecorator(new FuelCar());
car.describe();
}
}
=====結果=====
紅色的燃油車
以上看起來裝飾器模式和橋接模式有非常大的相似性,那麼到底這兩種模式有什麼區別呢?
- 橋接模式是為了讓兩個抽象的具體實現能夠進行自由的組合,而在某一個抽象類中引入了另一個抽象類,通過抽象類之間的“搭橋”,為其子類相互合作提供了方便。而裝飾器模式中一個抽象是另一個抽象的子類,其要目的是為了讓裝飾器抽象類的實現類可以對被裝飾的抽象類的實現類進行裝飾。
- 橋接是通過抽象類的組合實現,裝飾器是通過抽象之間的組合+繼承實現的,橋接相對耦合性更低。