Java中具有泛型的工厂模式 [英] Factory pattern with generics in java

查看:124
本文介绍了Java中具有泛型的工厂模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在针对特定用例的泛型实现工厂方面遇到困难

I'm having trouble implementing factory with generics for a specific use case

我有模型课:

class BaseModel { }

class ModelA extends BaseModel { }

class ModelB extends BaseModel { }

以及相应的服务:

class Service<T extends BaseModel> { }

class ServiceA extends Service<ModelA> {}

class ServiceB extends Service<ModelB> {}

我的工厂"类,用于根据其服务的模型创建服务:

My Factory class, to create service according to the model it services:

class Factory {
    private Map<Class<? extends BaseModel>, Class<? extends Service>> registry;

    Factory(){
        registry = new HashMap<>();
        registry.put(ModelA.class, ServiceA.class);
        registry.put(ModelB.class, ServiceB.class);
    }

    Service getService(Class<? extends BaseModel> clazz) throws IllegalAccessException, InstantiationException {
        return registry.get(clazz).newInstance();
    }
}

还有一个使用工厂的类

class Handler<T extends BaseModel>{
    private Service<T> myService;

    Handler(Class<T> modelClass) {
        Factory fact = new Factory();
        try {
            myService = fact.getService(modelClass);
        } catch (IllegalAccessException | InstantiationException e) {
            e.printStackTrace();
        }
    }
}

对于使用工厂获得服务的生产线,我会收到一条警告:

I get an warning for the line that uses the factory to get the service:

"Unchecked assignment 'Service' to 'Service<T>'"

我理解为什么收到消息,因为 getService 方法返回 Service ,但是我需要 Service< T> ,并对如何操作感到困惑我可以更改代码以获取 Service< T>

I understand why I get the message, since the getService method returns Service, but I need Service<T> and puzzled about how I can change the code to get Service<T>

有什么建议吗?

谢谢!

推荐答案

Java泛型和继承有时会以违反直觉的方式进行交互,即 Service< ModelA> Service< BaseModel> .但是,您可以编写 getService()的两个实现,并显式调用服务构造函数(而不是通过反射).处理程序将需要模型的实例,以便Java覆盖将为您选择正确的服务构造函数.

Java generics and inheritance sometimes interact counter-intuitively, i.e. Service<ModelA> is not related (in terms of inheritance) to Service<BaseModel>. However, you can write two implementations of getService() and call the service constructors explicitly (not through reflection). Your Handler will need an instance of your Model, such that Java overriding will select the correct service-constructor for you.

我在原始答案中没有想到的是:您需要在工厂中捕获所有BaseModel实现(重写将选择最具体的方法),并且还必须针对接口来实现Service来提取字符串在一起.

What I haven't thought about in my original answer: you need to catch for all BaseModel implementations in your factory (overriding will pick the most specific method) and also your Service has to be implemented against an interface to pull the strings together.

class BaseModel { }

class ModelA extends BaseModel { }

class ModelB extends BaseModel { }

interface Service { }

class ServiceImplementation<T extends BaseModel> implements Service { }

class ServiceFactory {
    public static Service getService(ModelA model) { return new ServiceImplementation<ModelA>(); }
    public static Service getService(ModelB model) { return new ServiceImplementation<ModelB>(); }
    public static Service getService(BaseModel model) { 
        throw new UnsupportedOperationException("Unknown Service Model");
    }
}

class Handler<T extends BaseModel> {
    private Service service;

    Handler(T model) {
        service = ServiceFactory.getService(model);
    }
}

这篇关于Java中具有泛型的工厂模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆