【大話設計模式】-- 策略者模式(Strategy):它定義了演算法家族,分別封裝起來,讓他們之間可以互相替換,此模式讓演算法的變法,不會影響到使用演算法的客戶。
策略模式的核心就是遮蔽內部策略演算法,內部的演算法是可以隨時替換,對外部是沒有感知的。若新增或修改內部的演算法,只需要修改或者擴充套件相應的策略類,客戶端的程式碼無需改動,符合設計模式中一個重要的原則:開閉原則。
一. 業務需求背景
1.需求目的:
使用者可以進行對某種配置進行預約,到達配置的預約時間點,根據Redis佇列的預約號執行預約,不同型別的配置預約操作邏輯完全不同。
2.流程圖:
二. 使用策略模式的緣由
此業務由於是要支援不同配置的預約,以及後期可能會有很多種型別的配置,而且不同型別的配置又完成不同,如果直接編碼,後期的擴充套件性以及維護性會比較麻煩。
1.正常程式碼實現:
<?php
public function makeReservation($mainkey){
$type = getReservationTypeByMainkey($mainkey);
switch($type):{
case 'A':
$this->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.策略模式實現
<?php
interface ReservationStrategy
{
//執行預約配置邏輯操作
public function makeReservation();
}
//策略處理類
class ReservationHandler
{
private $strategy = null;
public function __construct(ReservationStrategy $strategy){
$this->$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到這種結構帶來的好處。雖然在這個業務上,這種結構的優勢並沒有特別的明顯,甚至可能有點增加程式碼量,但是我相信在後期擴充套件以及維護方便是有很大的好處的。記錄這篇文章,主要是想要記錄自己的思考方式以及學習體會,如果有一些不太對的地方歡迎大家指正,一起進步!!