1. 程式人生 > >策略模式在PHP業務程式碼的實踐

策略模式在PHP業務程式碼的實踐

>【大話設計模式】-- 策略者模式(**Strategy**):它定義了演算法家族,分別封裝起來,讓他們之間可以互相替換,此模式讓演算法的變法,不會影響到使用演算法的客戶。 **策略模式**的核心就是遮蔽內部策略演算法,內部的演算法是可以隨時替換,對外部是沒有感知的。若新增或修改內部的演算法,只需要修改或者擴充套件相應的策略類,客戶端的程式碼無需改動,符合設計模式中一個重要的原則:開閉原則。 ## 一. 業務需求背景 1.需求目的: 使用者可以進行對某種配置進行預約,到達配置的預約時間點,根據Redis佇列的預約號執行預約,不同型別的配置預約操作邏輯完全不同。 2.流程圖:![](https://cdn.learnku.com/uploads/images/202101/21/63958/NxQZWJEiUo.png!large) ## 二. 使用策略模式的緣由 此業務由於是要支援不同配置的預約,以及後期可能會有很多種型別的配置,而且不同型別的配置又完成不同,如果直接編碼,後期的擴充套件性以及維護性會比較麻煩。 1.正常程式碼實現: ```php reservationAConfig($mainkey); break; case 'B': $this->reservationBConfig($mainkey); break; ..... } } private function reservationAConfig($mainkey){ //這裡進行A配置的預約邏輯操作 } private function reservationBConfig($mainkey){ //這裡進行B配置的預約邏輯操作 } private function getReservationTypeByMainkey($mainkey){ //根據預約號獲取預約配置的型別 } ``` 這樣子的實現也是可以滿足業務需求,程式碼的可讀性也還好。但是會有一個問題,這種預約的配置種類會很多,會導致switch的語句會越來越多,也可能會修改一些預約配置邏輯。這樣子的話就需要修改原來的程式碼,對於程式碼質量來說,這並不是一種好的現象。 2.策略模式實現 ![](https://cdn.learnku.com/uploads/images/202101/21/63958/bppuiWzGhS.png!large) ```php $strategy = $strategy; } //封裝了策略執行的邏輯,所有執行的預約配置統一呼叫這個方法 public function makeReservation(){ $this->$strategy->makeReservation(); } } //A配置的具體策略類 class AReservationStrategy implements ReservationStrategy { public function makeReservation(){ //這裡執行A配置的邏輯操作 ; } class ReservationFacaory { public static function getReservationInstance($mainkey){ //這裡可以根據預約號做具體邏輯生成策略物件 } } //預約控制器程式碼 class ReservationController { public function makeReservation($mainkey){ //根據工廠物件建立預約策略例項 $reservation = ReservationFacaory::getReservationInstance($mainkey); //傳入例項給策略處理類 $handler = new ReservationHandler($reservation); //執行預約策略 $handler->makeReservation(); } } ``` 以上程式碼使用了**工廠模式**以及**策略模式**的結合,其中**ReservationHandler**類作為處理上下文的類,通過依賴注入相應的策略類,直接呼叫**makeReservation**方法。在客戶端程式碼只需要呼叫此方法即可,即使後期預約邏輯也無需改動客戶端的程式碼。在此業務需求,因為需求並不是很大,所以工廠類只是簡單實現。如果想要更完善,工廠類根據反射機制以及約定好的類名動態生成例項,這樣後期如果擴充套件型別,只需要實現相應的介面即可,無需改動其他程式碼,很方便擴充套件。 ## 總結 實踐才能出真知。以前看大話**設計模式**這本書,總覺得自己看了好多遍但是還是雲裡霧裡的,不知道為什麼需要這種程式碼結構。但是通過一個小需求設計這麼一個結構,我很快就能get到這種結構帶來的好處。雖然在這個業務上,這種結構的優勢並沒有特別的明顯,甚至可能有點增加程式碼量,但是我相信在後期擴充套件以及維護方便是有很大的好處的。記錄這篇文章,主要是想要記錄自己的思考方式以及學習體會,如果有一些不太對的地方歡迎大家指正,一起進