一 : 策略模式常用场景
- 当有同一种行为,不同的实现方式时
- 当出现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测试