工厂模式结合注解与枚举实现


此demo以乐器为例,实现获取service层实现类的工厂,利用了SpringBean的注册原理。相同接口多个不同实现在工作中比较常见,所以这种使用也是最基础的。

逻辑:通过在实现类上标注注解,程序启动时将实现类放入map中,key为注解中的枚举值,value为Bean,程序需使用的地方直接从map中获取即可。

此例中注解为乐器类枚举值,通常工作开发过程中,InstrumentType以参数传递,事先并不可知,根据这个参数选择对应的实现并调用方法。

乐器类型枚举类

/**
 * @author : wind-myf
 * @desc : 乐器类型枚举
 */
public enum InstrumentTypeEnum {
    GENERAL("GENERAL","通用乐器"),
    PIANO("PIANO","钢琴"),
    GUITAR("GUITAR","吉他"),
    HORN("HORN","喇叭"),
    DRUM("DRUM","鼓");

    private String code;
    private String desc;

    InstrumentTypeEnum(String code,String desc){
        this.code = code;
        this.desc = desc;
    }

    public String getCode() {
        return code;
    }

    public String getDesc() {
        return desc;
    }
}

乐器注解类

/**
 * 乐器类注解
 * @author wind_myf
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface InstrumentAnnotation {
    String instrumentType() default "GENERAL";
}

Service 层接口

/**
 * @author : wind-myf
 * @desc : 乐器类 Service
 */
public interface InstrumentService {

    /**
     * 弹奏乐器
     * @param userName 用户名
     * @return String
     */
    String playInstrument(String userName);
}

Service接口实现类

1 通用实现类

/**
 * @author : wind-myf
 * @desc : 通用实现类
 */
@Service("generalService")
@InstrumentAnnotation(instrumentType = "GENERAL")
public class GeneralServiceImpl implements InstrumentService {
    @Override
    public String playInstrument(String userName) {
        // 模拟业务逻辑
        String result = userName + "play the general instrument";
        System.out.println(userName + "play the general instrument - " + System.currentTimeMillis());
        return result;
    }
}

2 钢琴实现类

/**
 * @author : wind-myf
 * @desc : 钢琴实现类
 */
@Service("pianoService")
@InstrumentAnnotation(instrumentType = "PIANO")
public class PianoServiceImpl implements InstrumentService {
    @Override
    public String playInstrument(String userName) {
        // 模拟业务逻辑
        String result = userName + "play the piano";
        System.out.println(userName + "play the piano - " + System.currentTimeMillis());
        return result;
    }
}

3 吉他实现类

/**
 * @author : wind-myf
 * @desc : 吉他实现类
 */
@Service("guitarService")
@InstrumentAnnotation(instrumentType = "GUITAR")
public class GuitarServiceImpl implements InstrumentService {
    @Override
    public String playInstrument(String userName) {
        // 模拟业务逻辑
        String result = userName + "play the guitar";
        System.out.println(userName + "play the guitar - " + System.currentTimeMillis());
        return result;
    }
}

4 鼓实现类

/**
 * @author : wind-myf
 * @desc : 鼓实现类
 */
@Service("drumService")
@InstrumentAnnotation(instrumentType = "DRUM")
public class DrumServiceImpl implements InstrumentService {
    @Override
    public String playInstrument(String userName) {
        // 模拟业务逻辑
        String result = userName + "play the drum";
        System.out.println(userName + "play the drum - " + System.currentTimeMillis());
        return result;
    }
}

5 喇叭实现类

/**
 * @author : wind-myf
 * @desc : 喇叭实现类
 */
@Service("hornService")
@InstrumentAnnotation(instrumentType = "HORN")
public class HornServiceImpl implements InstrumentService {
    @Override
    public String playInstrument(String userName) {
        // 模拟业务逻辑
        String result = userName + "play the horn";
        System.out.println(userName + "play the horn - " + System.currentTimeMillis());
        return result;
    }
}

工厂类

方式一:实现 ApplicationContextAware

/**
 * @author : wind-myf
 * @desc : 乐器工厂 类,实现 ApplicationContextAware方式
 */
@Component
public class InstrumentFactory implements ApplicationContextAware {
    private static HashMap<String, InstrumentService> instrumentServiceMap = new HashMap<>();
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        // 获取包含音乐注解的类
        Map<String, Object> beansWithAnnotationMap = applicationContext.getBeansWithAnnotation(InstrumentAnnotation.class);
        for (Object bean : beansWithAnnotationMap.values()) {
            InstrumentAnnotation annotation = bean.getClass().getAnnotation(InstrumentAnnotation.class);
            if (annotation == null){
                continue;
            }
            System.out.println(bean);
            instrumentServiceMap.put(annotation.instrumentType(), (InstrumentService) bean);
        }
    }

    public static InstrumentService getInstrumentService(String instrumentType){
        return instrumentServiceMap.get(instrumentType);
    }
}

方式二:构造器+@Autowired注解

/**
 * @author : wind-myf
 * @desc : 乐器工厂 类 (使用构造器方式)
 */
@Component
public class InstrumentFactoryNew{
    private static HashMap<String, InstrumentService> instrumentServiceMap = new HashMap<>();

    @Autowired
    public InstrumentFactoryNew(List<InstrumentService> instrumentServices){
        for (InstrumentService instrumentService : instrumentServices) {
            InstrumentAnnotation annotation = instrumentService.getClass().getAnnotation(InstrumentAnnotation.class);
            if (annotation == null){
                continue;
            }
            System.out.println(instrumentService);
            instrumentServiceMap.put(annotation.instrumentType(),instrumentService);
        }
    }

    public static InstrumentService getInstrumentService(String instrumentType){
        return instrumentServiceMap.get(instrumentType);
    }
}

测试方法

@Test
    void testInstrumentFactory(){
        InstrumentService instrumentService = InstrumentFactory.getInstrumentService(InstrumentTypeEnum.PIANO.getCode());
        Assert.isTrue(instrumentService != null,"获取工厂类失败");
        String playInstrument = instrumentService.playInstrument("张三");
        System.out.println("playInstrument = " + playInstrument);
    }

    @Test
    void testInstrumentFactoryNew(){
        InstrumentService instrumentService = InstrumentFactoryNew.getInstrumentService(InstrumentTypeEnum.PIANO.getCode());
        Assert.isTrue(instrumentService != null,"获取工厂类失败");
        String playInstrument = instrumentService.playInstrument("李四");
        System.out.println("playInstrument = " + playInstrument);
    }

以上代码可直接运行,根据实际需求替换代码即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尘风-随手记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值