Java設計模式之《裝飾器模式》及應用場景

原創文章,轉載請標註出處:Java設計模式之《裝飾器模式》及應用場景html

1、概述

裝飾器模式做用是針對目標方法進行加強,提供新的功能或者額外的功能。java

不一樣於適配器模式和橋接模式,裝飾器模式涉及的是單方,和代理模式相同,並且目標必須是抽象的。設計模式

而實際上,裝飾器模式和代理模式的實現方式基本一致,只在目標的存在上有些差異,這個後面咱們具體講述。ide

2、初步分析

上面提到了兩點:測試

  • 涉及的是單方
  • 目標是抽象的

咱們來想一下,所謂單方主要指的是在整個裝飾器模式中不存在雙方調用,要解決的也不是雙方調用的問題,而是解決單方提供對外服務的問題,這個單方在自行對外提供服務時,功能不足,或者咱們須要額外添加一些新功能,這時就可使用裝飾器模式,來對這個單方進行加強。this

目標抽象的意思是由於咱們須要經過實現接口的方式來進行加強,所以目標必須抽象爲接口。設計

3、實例

下面咱們用咱們生活中的一個例子來講明,咱們用房子來做爲目標:代理

房子接口:Housecode

/**
 * 目標接口:房子
 */
public interface House {
    void output();
}

具體的房子:DonghaoHousehtm

/**
 * 房子實現類
 */
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();
    }
}

執行結果爲:

這是針對房子的前段裝飾加強
這是董浩的房子
這是針對房子的後段裝飾加強

4、解析

經過上面的例子咱們能夠看出,除了測試類外,只剩下接口和實現類了,即便是裝飾器類也是目標接口的一個字類,這更能說明單方的說法,模式中全部的類都屬於目標方。至於目標是抽象的更是如此,只有目標是抽象的,纔可使用裝飾器模式來進行加強。

上面咱們說過裝飾器模式與代理模式基本相同,只存在少量差異。

咱們須要從概念上了解代理和裝飾的區別:

  • 代理是全權代理,目標根本不對外,所有由代理類來完成。
  • 裝飾是加強,是輔助,目標仍然能夠自行對外提供服務,裝飾器只起加強做用。

上面兩點提現到代碼實現中是這樣的:
代理模式

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("這是針對房子的後段裝飾加強");
    }
}

看出來了嗎,裝飾器中持有的目標實例是從構造器傳入的,而代理中持有的目標實例是本身建立的。

那麼這裏又出現一個區別,代理模式和裝飾器模式雖然都依賴於目標接口,可是代理針對的目標實現類是固定的,而裝飾器模式能夠隨意指定,也就是說目標是能夠自有擴展的。

5、使用場景

裝飾器模式就是使用在對已有的目標功能存在不足,須要加強時,前提是目標存在抽象接口。

6、總結

咱們要明白代理模式和裝飾器模式的區別,區分兩者的使用場景,以下圖:


同系列文章:

相關文章
相關標籤/搜索