使用原因和场景
在工作中经常会遇到一个接口有很多实现类,然后需要定义一个统一的入口去调用,如果每次都注入不同的实现类,不符合Java的对开放-关闭原则(Open-Closed Principle, OCP),且代码冗余不好看。
//使用了策略模式
@Autowired
private Map<String, OrderService> beanFactory = Maps.newConcurrentMap();
Spring 会在启动时,自动查找实现了该接口的 bean,放到这个Map中去。 key为bean的名字,value为 实现了该接口的所有的 bean。
注意:这里只有在map的key为string类型时才有效;
具体的代码实现
1、定义接口的调用工厂
初始化所有的OrderService实现类并通过OrderFactory 来调用具体的实现类
Map<String, OrderService> String参数 是定义的service的类名,可以使用@Component(“AA”) 重命名为AA
@Slf4j
@Service
public class OrderFactory {
/**
*策略模式
*会在spring启动时把所有OrderService加载到map中
*关键在于 @Autowired
**/
@Autowired
private Map<String, OrderService> beanFactory = Maps.newConcurrentMap();
public OrderService get(String key){
OrderService orderService = beanFactory.get(key);
if(orderService == null) {
throw new RuntimeException("no OrderService defined!");
}
return beanFactory.get(key);
}
public void put(String key, OrderService service){
beanFactory.put(key, service);
}
}
2、定义接口类
定义一个接口,用于提供统一的调用方法
public interface OrderService{
/**
*处理订单
* @params orderNo 订单号
* @params orderType 订单类型
* */
String dealOrdering(String orderNo,String orderType );
}
3、定义接口抽象实现类
定义一个抽象类,实现OrderService接口,提供多个实现类的通用方法,并提供一个业务逻辑处理抽象方法,让具体实现类各自实现自己的业务逻辑。所有通用的逻辑都可以抽出来,放在这个类里面处理。
@Service
public abstract class OrderAbstractService implements OrderService{
//提供统一的逻辑校验等方法
public boolean checkRepay(String orderNo,String orderType ){
Boolean check=false;
//可以进行防重复校验
//日志记录
//其他
return check;
}
//重写接口方法,做一些通用的逻辑处理,比如防重等
@Override
public String dealOrdering(String orderNo,String orderType ){
//1.防重校验,如果校验为true,则不需要走dealOrder方法,直接返回Success
if( checkRepay(orderNo,orderType )){
return "Success";
}
return dealOrder(orderNo,orderType );
}
//抽象方法,各自具体实现类的逻辑处理
public abstract String dealOrder(String orderNo,String orderType);
}
4、定义接口的多个实际业务实现类
下方是三个具体的实现类,继续抽象类OrderAbstractService ,实现各自业务逻辑
@Slf4j
@Component("OrderBenchiCar")
public class OrderBenchiCarService extends OrderAbstractService {
//实现抽象类的dealOrder,具体实现逻辑处理
@Override
public String dealOrder(String orderNo,String orderType) {
String returnMsg="";
//2.处理奔驰汽车订单的生产逻辑
//3.调用结果
return returnMsg;
}
}
@Slf4j
@Component("OrderBaomaCar")
public class OrderBaomaCarService extends OrderAbstractService {
//实现抽象类的dealOrder,具体实现逻辑处理
@Override
public String dealOrder(String orderNo,String orderType) {
String returnMsg="";
//2.处理宝马汽车订单的生产逻辑
//3.调用结果
return returnMsg;
}
}
@Slf4j
@Component("OrderAodiCar")
public class OrderAodiCarService extends OrderAbstractService {
//实现抽象类的dealOrder,具体实现逻辑处理
@Override
public String dealOrder(String orderNo,String orderType) {
String returnMsg="";
//2.处理奥迪汽车订单的生产逻辑
//3.调用结果
return returnMsg;
}
}
5、实际业务调用类
该类为所有此类型业务处理的统一入口,用来接收不同业务类型,然后进行统一调用处理
@Slf4j
@Service
public class OrderControl {
//统一入口方法,根据传入的ordertype来决定具体的实现类
//@Async代表异步处理,也可不用,看具体场景
@Async
public void commit(String orderNo,String orderType) {
String Msg="";//定义返回参数
//orderType 为实现类的别名 OrderAodiCar OrderBaomaCar OrderBenchiCar
//1.所有类型都直接调用即可
Msg= OrderFactory.get(orderType).dealOrdering(orderNo, orderType);
//2.其他逻辑处理
if("OrderBenchiCar".equals(orderType)){
//其他逻辑
if("Success".equals(Msg)){
....
}
}else if("OrderBenchiCar".equals(orderType)){
}else if("OrderBenchiCar".equals(orderType)){
}
}
}