springboot中使用工厂方法

参考:

https://www.shuzhiduo.com/A/ke5jZwbO5r/

https://blog.csdn.net/Li_haiyu/article/details/124341345

工厂方法是我们实际工作中经常用到的。

比如下面的例子,一个接口有多个实现类,我们自然而然会想到使用工厂方法。

//接口类
public interface ReportService {
    String getResult();
}

//实现类
public class ReportServiceA1 implements ReportService {
    @Override
    public String getResult() {
        return "我是A1";
    }
}

//实现类
public class ReportServiceA2 implements ReportService {
    @Override
    public String getResult() {
        return "我是A2";
    }
}

为了构造实现类的实例,我们创建一个工厂类

public class ReportFactory {
    public static ReportService createService(String name){
        if(name.equals("A1")){
            return new ReportServiceA1();
        }else if(name.equals("A2")){
            return new ReportServiceA2();
        }else{
            throw new IllegalArgumentException("不支持的类型");
        }
    }

    public static void main(String[] args) {
        ReportService a1 = createService("A1");
        String result = a1.getResult();
        System.out.println(result);
    }
}

输出:

我是A1

 

其实在SpringBoot中,也支持以依赖注入的方式实现工厂方法。

我们只需要对类稍加改造即可。

//接口实现不变
public interface ReportService {
    String getResult();
}

//给实现类加上名字
@Component("A1")
public class ReportServiceA1 implements ReportService {
    @Override
    public String getResult() {
        return "我是A1";
    }
}

//给实现类加上名字
@Component("A2")
public class ReportServiceA2 implements ReportService {
    @Override
    public String getResult() {
        return "我是A2";
    }
}

新工厂类实现

@Service
public class ReportFactory {
    //这个地方是关键,项目启动时springboot会被所有ReportService实现类注入到这个map中
    @Autowired
    private final Map<String,ReportService> map=new ConcurrentHashMap<>();

    public ReportService get(String name){
        return map.get(name);
    }


}

测试一下,可以看出对应每个不同的实现类都只有唯一的一个实例,并且建立了name和实例的映射关系。

而且这种工厂方法的实现比自己手写if/else工厂方法优雅多了。

@SpringBootTest(classes= Application.class)
class ReportFactoryTest {

    @Autowired
    private ReportFactory reportFactory;

    @Test
    void get() {
        ReportService a1 = reportFactory.get("A1");
        ReportService a11 = reportFactory.get("A1");
        System.out.println(a1);
        System.out.println(a11);
        System.out.println( a1.getResult());
        ReportService a2 = reportFactory.get("A2");
        System.out.println(a2.getResult());
    }
}

输出:

cn.jinka.gcdp.metacenter.application.metadata.ReportServiceA1@d3e9629
cn.jinka.gcdp.metacenter.application.metadata.ReportServiceA1@d3e9629
我是A1
我是A2

 

posted @ 2022-07-12 10:15  Mars.wang  阅读(1095)  评论(0)    收藏  举报