一、引言
裝飾模式是什麼?爲什麼有裝飾模式?裝飾模式怎麼實現?
- 裝飾器模式(Decorator Pattern)允許向一個現有的對象添加新的職責,同時又不改變其結構。這種類型的設計模式屬於結構型模式,它是作爲現有的類的一個包裝。
- 裝飾模式就是用來給一個已有的類添加額外的功能。
二、實現方式
我們先來看一個需求:
簡單的手機(SimplePhone)在接收來電的時候會發出聲音來提醒主人;現在要將該手機升級(1)先升級爲帶振動的手機(JarPhone),使得手機在接收來電不僅有聲音,還有振動。(2)再升級爲燈光手機(ComplexPhone)
,使得來電不僅有聲音,振動,還有燈光提醒。
這個需求相當於在原有的手機上不斷新增功能,因此可以用到裝飾模式。
先上類圖:
由圖可以看出,我們要爲手機添加新的功能,於是寫了一個手機裝飾類(抽象),然後要新增什麼功能的手機,繼承與他就好了。
而新功能的手機和原來的則是組合關係,畢竟要拿原來的手機進行升級嘛。
下面看代碼實現:
/**
* 手機接口
*/
public interface Phone {
//接聽方法
public void call();
}
/**
* 簡單手機
*/
public class SimplePhone implements Phone {
public void call() {
System.out.println("響鈴");
}
}
/**
* 手機裝飾類,抽象
*/
public abstract class PhoneDecorator implements Phone{
protected Phone phone;//組合了一個準備要升級的手機
public PhoneDecorator(Phone phone) {
this.phone = phone;
}
public abstract void call();
}
public class JarPhone extends PhoneDecorator {
public JarPhone(Phone phone) {
super(phone);
}
public void call() {
//調用原來手機的接聽
phone.call();
//新增振動功能
System.out.println("振動");
}
}
public class ComplexPhone extends PhoneDecorator {
public ComplexPhone(Phone phone) {
super(phone);
}
public void call() {
//調用原來手機的接聽
phone.call();
//新增燈光功能
System.out.println("燈光");
}
}
下面是Main方法
public static void main(String[] args) {
SimplePhone phone = new SimplePhone();
System.out.println("-------------簡單手機接聽------------------");
phone.call();
System.out.println("-------------升級爲帶振動手機接聽------------------");
JarPhone jarPhone = new JarPhone(phone);
jarPhone.call();
System.out.println("-------------升級爲帶振動+燈光手機接聽------------------");
ComplexPhone complexPhone = new ComplexPhone(jarPhone);
complexPhone.call();
}
下面是運行結果:
由結果可知,我們在沒動原來手機的情況下,對它進行了改造,增加了一些新的功能,這就是裝飾模式。
三、結束
裝飾模式相對簡單,本意就是在不動原來類的情況下新增功能,滿足開閉原則。