原創文章,轉載請标注出處:Java設計模式之《裝飾器模式》及應用場景
一、概述
裝飾器模式作用是針對目标方法進行增強,提供新的功能或者額外的功能。
不同于擴充卡模式和橋接模式,裝飾器模式涉及的是單方,和代理模式相同,而且目标必須是抽象的。
而實際上,裝飾器模式和代理模式的實作方式基本一緻,隻在目标的存在上有些差别,這個後面我們具體講述。
二、初步分析
上面提到了兩點:
- 涉及的是單方
- 目标是抽象的
我們來想一下,所謂單方主要指的是在整個裝飾器模式中不存在雙方調用,要解決的也不是雙方調用的問題,而是解決單方提供對外服務的問題,這個單方在自行對外提供服務時,功能不足,或者我們需要額外添加一些新功能,這時就可以使用裝飾器模式,來對這個單方進行增強。
目标抽象的意思是因為我們需要通過實作接口的方式來進行增強,是以目标必須抽象為接口。
三、執行個體
下面我們用我們生活中的一個例子來說明,我們用房子來作為目标:
房子接口:House
/**
* 目标接口:房子
*/
public interface House {
void output();
}
具體的房子:DonghaoHouse
/**
* 房子實作類
*/
public class DonghaoHouse implements House {
@Override
public void output() {
System.out.println("這是董浩的房子");
}
}
具體的房子:DongliangHouse
/**
* 房子實作類
*/
public class DongliangHouse implements House {
@Override
public void output() {
System.out.println("這是董量的房子");
}
}
裝飾器:Decorator
public class Decorator implements House {
private House house;
public Decorator(House house){
this.house = house;
}
@Override
public void output() {
System.out.println("這是針對房子的前段裝飾增強");
house.output();
System.out.println("這是針對房子的後段裝飾增強");
}
}
測試類:
public class Clienter {
public static void main(String[] args) {
House donghaoHouse = new DonghaoHouse();
House decorator = new Decorator(donghaoHouse);
decorator.output();
}
}
執行結果為:
這是針對房子的前段裝飾增強
這是董浩的房子
這是針對房子的後段裝飾增強
四、解析
通過上面的例子我們可以看出,除了測試類外,隻剩下接口和實作類了,即使是裝飾器類也是目标接口的一個字類,這更能說明單方的說法,模式中所有的類都屬于目标方。至于目标是抽象的更是如此,隻有目标是抽象的,才可以使用裝飾器模式來進行增強。
上面我們說過裝飾器模式與代理模式基本相同,隻存在少許差别。
我們需要從概念上了解代理和裝飾的差別:
- 代理是全權代理,目标根本不對外,全部由代理類來完成。
- 裝飾是增強,是輔助,目标仍然可以自行對外提供服務,裝飾器隻起增強作用。
上面兩點提現到代碼實作中是這樣的:
代理模式
public class Proxy implements House {
private House house;
public Decorator(){
this.house = new DonghaoHouse();
}
@Override
public void output() {
System.out.println("這是針對目标的前段增強");
house.output();
System.out.println("這是針對目标的後段增強");
}
}
裝飾模式
public class Decorator implements House {
private House house;
public Decorator(House house){
this.house = house;
}
@Override
public void output() {
System.out.println("這是針對房子的前段裝飾增強");
house.output();
System.out.println("這是針對房子的後段裝飾增強");
}
}
看出來了嗎,裝飾器中持有的目标執行個體是從構造器傳入的,而代理中持有的目标執行個體是自己建立的。
那麼這裡又出現一個差別,代理模式和裝飾器模式雖然都依賴于目标接口,但是代理針對的目标實作類是固定的,而裝飾器模式可以随意指定,也就是說目标是可以自有擴充的。
五、使用場景
裝飾器模式就是使用在對已有的目标功能存在不足,需要增強時,前提是目标存在抽象接口。
六、總結
我們要明白代理模式和裝飾器模式的差別,區分二者的使用場景,如下圖:
同系列文章:
- Java設計模式之《擴充卡模式》及應用場景
- Java設計模式之《外觀模式》及應用場景
- Java設計模式之《橋接模式》及應用場景
- Java設計模式之《單例模式》及應用場景
- Java設計模式之《觀察者模式》及應用場景
- Java設計模式之《調停者模式》及應用場景
- Java設計模式之《代理模式》及應用場景
- Java設計模式之《職責鍊模式》及應用場景
- Java設計模式之《享元模式》及應用場景
- Java設計模式之《建構者模式》及應用場景
- Java設計模式之《模闆模式》及使用場景
- Java設計模式之《裝飾器模式》及應用場景
- Java設計模式之《工廠方法模式》及使用場景
- Java設計模式之《抽象工廠模式》及使用場景