侧边栏壁纸
博主头像
析木之林博主等级

山不让尘,川不辞盈。

  • 累计撰写 63 篇文章
  • 累计创建 59 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录

Java如何实现一个接口多个实例

析木
2023-02-26 / 0 评论 / 3 点赞 / 160 阅读 / 5485 字 / 正在检测是否收录...

背景

在实际工作中,我们经常会遇到一个接口及多个实现类的场景,并且在不同的条件下会使用不同的实现类。

实现方法

  1. 使用Spring特性,ApplicationContext的getBeansOfType来实现;
  2. 策略模式实现;

方法一:

定义抽象接口:

/**
 * 支付实例
 */
public interface PayAbstractService {

    PayTypeEnum getCode();

    /**
     * 支付
     * @return
     */
    String pay();
}

枚举:

/**
 * 支付类型枚举
 */
public enum PayTypeEnum {
    // 微信支付
    WECAHT_PAY,
    // 支付宝支付
    ALI_PAY,
    ;
}

实现类:

/**
 * 支付宝支付
 */
@Service
public class AliPayService implements PayAbstractService {
    @Override
    public PayTypeEnum getCode() {
        return PayTypeEnum.ALI_PAY;
    }

    @Override
    public String pay() {
        return "支付宝支付";
    }
}

/**
 * 微信支付
 */
@Service
public class WeChatPayService implements PayAbstractService {
    @Override
    public PayTypeEnum getCode() {
        return PayTypeEnum.WECAHT_PAY;
    }

    @Override
    public String pay() {
        return "微信支付";
    }
}

工厂类:

@Component
public class PayAwareFactory implements ApplicationContextAware {

    private static Map<PayTypeEnum, PayAbstractService> payBeanMap;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Map<String, PayAbstractService> map = applicationContext.getBeansOfType(PayAbstractService.class);
        payBeanMap = new HashMap<>();
        map.forEach((k, v) -> payBeanMap.put(v.getCode(), v));
    }

    /**
     * 获取支付服务实例
     * @param payTypeEnum
     * @see PayTypeEnum
     * @return
     */
    public static PayAbstractService getService(PayTypeEnum payTypeEnum) {
        return payBeanMap.get(payTypeEnum);
    }
}

验证方法:

@SpringBootTest
public class Tests {

    @Resource
    PayAwareFactory payAwareFactory;

    @Test
    public void awaeTest(){
        PayAbstractService service = payAwareFactory.getService(PayTypeEnum.WECAHT_PAY);
        System.out.println(service.pay());
        PayAbstractService service = payAwareFactory.getService(PayTypeEnum.ALI_PAY);
        System.out.println(service.pay());
    }
}

方法二(策略模式):

定义抽象接口:

/**
 * 支付实例
 */
public interface PayAbstractService {
    /**
     * 支付
     * @return
     */
    String pay();
}

枚举:

/**
 * 支付类型枚举
 */
public enum PayTypeEnum {
    // 微信支付
    WECAHT_PAY(1, "weChatPayService"),
    // 支付宝支付
    ALI_PAY(2, "aliPayService"),
    ;

    private int code;
    private String name;

    PayTypeEnum(int code, String name){
        this.code = code;
        this.name = name;
    }

    public int getCode(){
        return code;
    }

    public String getName(){
        return name;
    }
}

实现类:

/**
 * 支付宝支付
 */
@Service("aliPayService")
public class AliPayService implements PayAbstractService {
    @Override
    public String pay() {
        return "支付宝支付";
    }
}

/**
 * 微信支付
 */
@Service("weChatPayService")
public class WeChatPayService implements PayAbstractService {
    @Override
    public String pay() {
        return "微信支付";
    }
}

工厂类:

@Component
public class PayFactory {

    // Spring会将实现PayAbstractService接口的Bean,将首字母小写格式put到map。
    private final Map<String, PayAbstractService> payBeanMap = new ConcurrentHashMap<>();

    @Autowired
    public PayFactory(Map<String, PayAbstractService> map){
        map.forEach(payBeanMap::put);
    }

    /**
     * 获取支付服务实例
     * @param payTypeEnum
     * @see PayTypeEnum
     * @return
     */
    public PayAbstractService getService(PayTypeEnum payTypeEnum){
        return payBeanMap.get(payTypeEnum.getName());
    }
}

验证:

@SpringBootTest
public class Tests {
    @Resource
    PayFactory payFactory;

    @Test
    public void test(){
        PayAbstractService service = payFactory.getService(PayTypeEnum.WECAHT_PAY);
        System.out.println(service.pay());
        PayAbstractService service = payAwareFactory.getService(PayTypeEnum.ALI_PAY);
        System.out.println(service.pay());
    }
}

我这里这是写了2个简单的Demo,你可以根据你的业务具体来实现。


我是析木,希望你变的更强

3

评论区