一 : 策略模式常用場景
- 當有同一種行爲,不同的實現方式時
- 當出現switch case或 if else if 等語法時,爲了以後擴展方便時,我們通常可以考慮使用策略模式去實現
- 舉例如下:
① : 定義一個算法接口,有四個實現類,分別實現加減乘除,通過同一個接口不同的實現完成
②: 定義一個根據不同的VIP級別返回不同的折扣的接口,通過同一個接口不同的實現完成
③: 根據訂單類型,返回不同的商品價格,滴滴,餓了嗎,美團
二:使用案例
- 定義策略接口
/**
* 醫囑
*/
public interface DoctorOrderSevice {
/**
* 醫囑執行
* @return
*/
String executeDoctorOrder();
}
- 策略接口的具體實現
/**
* 檢查檢驗醫囑
*/
@Service("checkDoctorOrderSevice")
public class CheckDoctorOrderSeviceImpl implements DoctorOrderSevice {
@Override
public String executeDoctorOrder() {
//TODO 執行檢查檢驗醫囑的邏輯處理和業務驗證
return "我在執行檢查檢驗醫囑";
}
}
/**
* 診療診斷醫囑
*/
@Service("diagnosisDoctorOrderSevice")
public class DiagnosisDoctorOrderSeviceImpl implements DoctorOrderSevice {
@Override
public String executeDoctorOrder() {
//TODO 執行診療診斷醫囑的邏輯處理和業務驗證
return "我在執行診療診斷醫囑";
}
}
/**
* 藥品醫囑
*/
@Service("drugDoctorOrderSevice")
public class DrugDoctorOrderSeviceImpl implements DoctorOrderSevice {
@Override
public String executeDoctorOrder() {
//TODO 執行藥品醫囑的邏輯處理和業務驗證
return "我在執行藥品醫囑";
}
}
- 注入並動態匹配策略實現類
import com.lpf.design.dto.DoctorOrderDto;
import com.lpf.design.service.DoctorOrderSevice;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 策略匹配工廠
*/
@Component
public class StrategyFactory {
@Autowired
private final Map<String, DoctorOrderSevice> strategyMap = new ConcurrentHashMap<>();
public String getInstance(DoctorOrderDto doctorOrderDto){
return strategyMap.get(doctorOrderDto.getClassName()).executeDoctorOrder();
}
}
- 接口參數封裝
import lombok.Data;
@Data
public class DoctorOrderDto {
/**
* 醫囑種類名稱
*/
private String className;
}
- 對外暴露接口
@RestController
public class DoctorOrderController {
@Autowired
private StrategyFactory strategyFactory;
@PostMapping("/test")
public String executeDoctorOrder(@RequestBody DoctorOrderDto doctorOrderDto) {
return strategyFactory.getInstance(doctorOrderDto);
}
}
- 測試接口調用
單元測試
@RunWith(SpringRunner.class)
@SpringBootTest
public class DesignApplicationTests {
@Autowired
DoctorOrderController doctorOrderController;
@Test
public void contextLoads() {
DoctorOrderDto doctorOrderDto = new DoctorOrderDto();
doctorOrderDto.setClassName("diagnosisDoctorOrderSevice");
String s = doctorOrderController.executeDoctorOrder(doctorOrderDto);
System.err.println("打印結果:"+s);
}
}
打印結果:我在執行診療診斷醫囑
postman測試