iT邦幫忙

2021 iThome 鐵人賽

DAY 26
0
Software Development

幫自己搞懂物件導向和設計模式系列 第 26

Proxy 代理模式

今天要談到代理模式,其實跟昨天的裝飾器模式很類似。代理模式的目的在於,因應某些條件替換物件原本的行為。

同樣用昨天的例子,這裡有 BookPrinter 可以把書印出來

abstract class Printer {
  abstract print(): void
}

class BookPrinter extends Printer {
  genre: string;
  constructor(genre: string) {
    super()
    this.genre = genre
  }

  print(): string {
    return `This is a ${this.genre} book!`
  }
}

但我們希望這個 BookPrinter 只有在 "ready" 的時候才印書,如果尚未 "ready" 的話,就讓使用者知道 printer 還沒有準備好。這時候我們可以怎麼做呢?

首先,我們建立一個 BookPrinterProxy 類別。跟昨天的裝飾器很像,我們可以傳入物件到這個 proxy 當中,再由這個 proxy 幫我們「加料」做點事情。

這裡我們要做的事情就是,判斷 printer 是否 ready。這裡假設有一個 isReady 的變數,如果為 true,那麼就執行原有物件的功能;若為 false,那麼就讓 proxy 代為處理,印出 "Printer is not ready" 的訊息

class BookPrinterProxy extends Printer {
  printer: Printer;
  constructor(printer: Printer){
    super()
    this.printer = printer
  }

  print(): string {
    if (isReady) {
      return `${this.printer.print()}`
    } else {
      return 'Printer is not ready!'
    }
  }
}

實作結果如下:

const scienceBook = new BookPrinter('science')
const bookProxy = new BookPrinterProxy(scienceBook)
let isReady = false


bookProxy.print()  // Printer is not ready!

isReady = true

bookProxy.print()  // This is a science book!

代理模式

代理模式其實在平常的開發當中很常見,譬如協助我們管理權限、快取等等,讓我們可以不用更動原本的物件的情況下,面對其他各種狀況。

代理模式可以說是特別版的裝飾器模式,差別在於裝飾器模式著重在層層套嵌的擴展性,而代理模式則著重於面對不同條件下的應對(代理)方式。


上一篇
Decorator 裝飾器模式
下一篇
Facade 外觀模式
系列文
幫自己搞懂物件導向和設計模式30

尚未有邦友留言

立即登入留言