策略模式解决重复的if else问题

转载于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();
    }

}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值