Larvel使用策略模式 – 範例 : 訊息寄送執行器

前言:

今天想來記錄一下近期在Laravel專案中用到策略模式的實際演練,這樣的方式無非是解耦每個class所負責的事情,以及可以更加彈性的設計每個class的內容

外部參考資訊 : https://www.runoob.com/design-pattern/strategy-pattern.html

範例:

今天的範例是我們需要設計出訊息傳送的中央平台,可以將資料傳遞到Email、SMS、Slack等三個平台,也需要預留未來擴充其他平台的可能性

過往的寫法:

以往我們可以會設計三個ServiceClass,分別用於寄送三個平台的訊息例如: EmailService、SMSService、SlackService,然後在Controller中呼叫他像這個樣子

然後在Controller中呼叫

當然,我們也可以調整成上一篇提到的動態呼叫的寫法,讓原始碼更簡潔,像是這個樣子

PHP 動態呼叫函數(variable functions)與@see

只是在彈性上與邏輯的完整度上都比較缺乏,今天就記錄一下策略模式的使用方式

 

策略模式範例 :

實際上這個範例使用了策略模式+工廠模式來完整處理資料流

定義策略

跟先前相同,我們需要定義三個PlatformClass,分別處理不同平台的資料,並且都需要實作同一個Interface

下一步我們要定義一個執行器,概念上是三個Platform的上層邏輯,負責處理整個寄送資訊的資料流,也是從Controller呼叫的入口

簡單說明一下內容

Manager的部分後續說明,他是負責把platform new出來的class

Trigger是Notification的入口,只要將需要的參數傳入,後續會執行

1._set_payload,儲存參數
2._prepare,生成平台
3._send,呼叫平台的send()實際將資料送出

我們要說明的重點在_prepare身上,

我們不在_prepare身上直接new platform,而是透過Manager來處理,Manager就是類似工廠的概念,負責產出需要的物件

Manager大概可以長這個樣子

大概就是透過create() function將需要的Object物件new好回傳,這樣子可以更解耦每個class負責的事情

那麼我們就可以在Controller中這樣子呼叫

當然如果要再更嚴謹一些的話,就可以把所有payload都改成透過Dto 物件來傳遞

總結以上:

  1. 透過NotificationService作為服務入口
  2. 在Notification中透過Manager將需要的平台Object new出來
  3. 統一透過_send function來呼叫每個平台的Object的send() function來實際將資料送出

以上這樣子設計,如果需要多一個平台,只要多設計一個XXXXPlatform就可以了喔