1. 程式人生 > >靜態代理與裝飾模式

靜態代理與裝飾模式

靜態代理與裝飾模式

一、靜態代理

  1. 代理模式是指,為其他物件提供一種代理以控制對這個物件的訪問。在某些情況下,一個物件不適合或者不能直接引用另一個物件,而代理物件可以在客戶類和目標物件之間起到中介的作用。換句話說,使用代理物件,是為了在不修改目標物件的基礎上,增強主業務邏輯
  2. 客戶類真正的想要訪問的物件是目標類物件,但客戶類真正可以訪問的物件是代理物件。客戶類對目標物件的訪問是通過訪問代理物件來實現的
  3. 靜態代理是指,代理類在程式執行前就已經定義好,其與目標類的關係在程式執行前就已經確定。靜態代理類似於企業與企業的法律顧問間的關係。法律顧問與企業的代理關係,並不是在“官司”發生後才建立的,而是之前就確立好的一種關係。
  4. 靜態代理實現轉賬
    • 定義業務介面
      在這裡插入圖片描述
    • 定義目標類,實現了業務介面
      在這裡插入圖片描述
    • 定義代理類,同樣實現業務網介面,並且該代理類要將介面物件作為一個成員變數,還要定義一個帶參的構造器,這個引數為介面物件。目的是,將目標物件引入代理類,以便代理類呼叫目標類的目標方法。
      在這裡插入圖片描述
    • 定義客戶類 Client。在客戶類中首先要建立目標物件,再建立代理物件,並使用目標物件對其進行初始化。然後由代理物件來呼叫執行業務方法。
      在這裡插入圖片描述

二、裝飾模式

  1. 概述
    Decorator Pattern,能夠在不修改目標類也不使用繼承的情況下,動態地擴充套件一個類的 功能。它是通過建立一個包裝物件,也就是裝飾者來達到增強目標類的目的的。
  2. 裝飾者設計模式的實現有兩個要求:
    • 裝飾者類與目標類要實現相同的介面,或繼承自相同的抽象類。
    • 裝飾者類中要有目標類的引用作為成員變數,而具體的賦值一般通過帶參構造器完成。
    • 這兩個要求的目的是,在裝飾者類中的方法可以呼叫目標類的方法,以增強這個方法。 而增強的這個方法是通過重寫的方式進行的增強,所以要求實現相同的介面或繼承相同的抽 象類。
  3. 在裝飾者設計模式中,裝飾者類一般是不對目標類進行增強的。裝飾者類作為一個基類, 具體的裝飾者繼承自這個基類,對目標類進行具體的、單功能的增強。這樣做的好處是,在 很方便的情況下可以實現多重地、組合式地增強。
  4. 裝飾者基類就像是一個裝修公司的老闆,其不做任何具體的裝修工作。而具體的裝飾者 則相當於裝修公司中的木工、刷漆工、水電工等具體的裝修師傅。裝修公司的老闆可以根據 具體的裝修工程,任意組合式地呼叫不同工種的裝修工人。
  5. 裝飾者模式設計的實現
    下面的例子實現的功能是,對於目標類中的方法 doSome()進行功能增強。為該目標類 定義一個裝飾者類後,再定義兩個具體的裝飾者類:一個用於將 doSome()的返回值去掉前 後空格,一個用於將 doSome()的返回值小寫變大寫。當然,裝飾者模式允許構造一個裝飾 者增強鏈對目標類進行連線增強。
    • 定義業務介面ISomeService
      在這裡插入圖片描述
    • 定義目標類 SomeServiceImpl
      在這裡插入圖片描述
    • 定義裝飾者基類 SomeServiceWrapper
      在這裡插入圖片描述
    • 定義去空格裝飾者類 TrimDecorator
      在這裡插入圖片描述
    • 定義小寫變大寫裝飾者類 ToUpperCaseDecorator
      在這裡插入圖片描述
    • 定義測試類 MyTest
      對於第二次增強,需要注意的是,其帶參構造器中所帶引數,即要增強的目標物件是 trimDecorator,是第一次增強後的物件,也是一個具體裝飾者。這樣的話,形成了 trimDecorator 增強 service,而 toUpperCaseDecorator 增強 trimDecorator 的裝飾者增強鏈。
      在這裡插入圖片描述

三、裝飾者設計模式與靜態代理設計模式的對比

  1. 相同點:
    • 裝飾者類與目標類要求實現同一介面;靜態代理類與目標類要求也實現同一介面。
    • 裝飾者類與靜態代理類都可以實現增強目標類的功能。
    • 裝飾者類與靜態代理類中都具有目標類的引用,目的都是為了在其中呼叫目標類的方 法。
  2. 不同點
    • 裝飾者設計模式就是為了增強目標類;靜態代理設計模式是為了保護和隱藏目標物件, 讓客戶類只能訪問代理物件,而不能直接訪問目標物件。
    • 裝飾者類中的目標類的引用是通過帶參構造器傳入的;靜態代理類中的目標類的引用, 一般都是在代理類中直接建立的,目的就是為了隱藏目標物件。
    • 裝飾者基類一般不對目標物件進行增強,而是由不同的具體裝飾者進行增強的,且這 些具體的裝飾者可以形成增強鏈,對目標物件進行連續增強。靜態代理類會直接對目標物件 進行增強,需要哪些增強的功能,一次性在靜態代理類中完成,沒有增強鏈的概念。