转载于https://www.toudo.cn/article/9
前言
想必大家在开发中肯定遇到过某个场景使用了大量的if else 来处理不同的业务。
下面给大家介绍一种设计模式,可以优雅的解决这种问题,提高代码的扩展性、和美观性。
正文
下面给大家举个例子,这是几种汽车品牌
public interface CarTypeConstants {
static final String DAZHONG = "dazhong";
static final String BSJ = "bsj";
static final String BMW = "bmw";
static final String AUDI = "audi";
static final String BENCHI = "benchi";
}
根据不同的品牌,需要不同的品牌厂商去生产汽车,传统的实现方式如下:
@Service
public class MakeCarServiceImpl implements MakeCarService {
@Autowired
private AudiCarHandlerAdapter audiCarHandler;
@Autowired
private BenchiCarHandlerAdapter benchiCarHandler;
@Autowired
private BsjCarHandlerAdapter bsjCarHandler;
@Autowired
private DazhongCarHandlerAdapter dazhongCarHandler;
@Autowired
private BmwCarHandlerAdapter bmwCarHandler;
/**
* 根据不通品牌的汽车,需要不通的生产商去生产
*
* @param carType
* @return
*/
@Override
public String makeCar(String carType) {
// 传统处理方式
if (CarTypeConstants.AUDI.equals(carType)) {
return audiCarHandler.make();
} else if (CarTypeConstants.BENCHI.equals(carType)) {
return benchiCarHandler.make();
} else if (CarTypeConstants.BMW.equals(carType)) {
return bmwCarHandler.make();
} else if (CarTypeConstants.BSJ.equals(carType)) {
return bsjCarHandler.make();
} else if (CarTypeConstants.DAZHONG.equals(carType)) {
return dazhongCarHandler.make();
}
return "";
}
}
如何使用一行代码来解决上面的if else 呢
@Service
public class MakeCarServiceImpl implements MakeCarService {
@Autowired
private CarHandlerContext carHandlerContext;
@Override
public String makeCarV2(String carType) {
return carHandlerContext.getHandlerInstance(carType).make();
}
}
第一步
需要使用到自定义注解,定义好汽车类型
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface CarTypeHandler {
String value();
}
第二步
定义一个抽象类,声明一个抽象方法
public abstract class AbstractCarHandler {
public abstract String make();
}
第三步
声明每个品牌的处理器,来处理具体的业务
@Component
@CarTypeHandler(CarTypeConstants.AUDI)
public class AudiCarHandler extends AbstractCarHandler {
@Override
public String make() {
// 制造奥迪品牌车
System.out.println("制造出一辆奥迪....................");
return null;
}
}
@Component
@CarTypeHandler(CarTypeConstants.BENCHI)
public class BenchiCarHandler extends AbstractCarHandler {
@Override
public String make() {
// 制造奔驰品牌车
System.out.println("制造出一辆奔驰....................");
return null;
}
}
@Component
@CarTypeHandler(CarTypeConstants.BMW)
public class BmwCarHandler extends AbstractCarHandler {
@Override
public String make() {
// 制造宝马品牌车
System.out.println("制造出一辆宝马....................");
return null;
}
}
@Component
@CarTypeHandler(CarTypeConstants.BSJ)
public class BsjCarHandler extends AbstractCarHandler {
@Override
public String make() {
// 制造保时捷牌车
System.out.println("制造出一辆保时捷....................");
return null;
}
}
@Component
@CarTypeHandler(CarTypeConstants.DAZHONG)
public class DazhongCarHandler extends AbstractCarHandler {
@Override
public String make() {
// 制造大众品牌车
System.out.println("制造出一辆大众....................");
return null;
}
}
需要注意的一点,一定要使用注解@Component这样才能交给Spring容器来管理
第四步
定义上下文了
@Service
public class CarHandlerContext implements ApplicationContextAware {
@Autowired
private ApplicationContext applicationContext;
private static final Map<String, Class> handlerMap = new HashMap<>(16);
public AbstractCarHandler getHandlerInstance(String typeCode) {
Class clazz = handlerMap.get(typeCode);
return (AbstractCarHandler) applicationContext.getBean(clazz);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map<String, Object> beans = applicationContext.getBeansWithAnnotation(CarTypeHandler.class);
if (beans != null && beans.size() > 0) {
for (Object serviceBean : beans.values()) {
String payType = serviceBean.getClass().getAnnotation(CarTypeHandler.class).value();
handlerMap.put(payType, serviceBean.getClass());
}
}
}
}
这样就可以用以下一行代码实现了,如果以后需要添加一种品牌只需要新增一个处理器就可以,不需要再去更改逻辑代码了。
@Service
public class MakeCarServiceImpl implements MakeCarService {
@Autowired
private CarHandlerContext carHandlerContext;
@Override
public String makeCarV2(String carType) {
return carHandlerContext.getHandlerInstance(carType).make();
}
}