Java - 基于接口的框架中服务提供者的目的?

时间:2014-09-19 03:58:33

标签: java interface

我在下面列出了“Effective Java”及其引用的代码。

我的问题 -

  

为什么作者觉得服务提供者界面需要保存   按类名注册并反映实例化?不能了   静态工厂'providers'中的注册API被修改为   注册“服务”实例而不是“服务提供商”?

所以 -

// Maps service names to services
private static final Map<String, Service> services =
    new ConcurrentHashMap<String, Service>();
public static final String DEFAULT_PROVIDER_NAME = "<def>";

// Provider registration API
public static void registerDefaultService( Service s) {
    registerService(DEFAULT_PROVIDER_NAME, s);
}
public static void registerService(String name, Service s){
    services.put(name, s);
}

而不是下面文字中的示例。

摘自文本 -

  

服务提供者框架的可选第四个组件是a   服务提供者接口,提供者实现创建   他们的服务实施的实例。在没有服务的情况下   提供者接口,实现是通过类名和注册的   反思性地实例化(第53项)。对于JDBC,Connection   扮演服务接口DriverManager.registerDriver的一部分   是提供者注册API,DriverManager.getConnection是   服务访问API,而Driver是服务提供者接口。

这是代码 -

// Service provider framework sketch

// Service interface
public interface Service {
    ... // Service-specific methods go here
}

// Service provider interface
public interface Provider {
    Service newService();
}

// Noninstantiable class for service registration and access
public class Services {
    private Services() { }  // Prevents instantiation (Item 4)

    // Maps service names to services
    private static final Map<String, Provider> providers =
        new ConcurrentHashMap<String, Provider>();
    public static final String DEFAULT_PROVIDER_NAME = "<def>";

    // Provider registration API
    public static void registerDefaultProvider(Provider p) {
        registerProvider(DEFAULT_PROVIDER_NAME, p);
    }
    public static void registerProvider(String name, Provider p){
        providers.put(name, p);
    }

    // Service access API
    public static Service newInstance() {
        return newInstance(DEFAULT_PROVIDER_NAME);
    }
    public static Service newInstance(String name) {
        Provider p = providers.get(name);
        if (p == null)
            throw new IllegalArgumentException(
                "No provider registered with name: " + name);
        return p.newService();
    }
}

提前致谢!!

2 个答案:

答案 0 :(得分:0)

本案例中的提供者是工厂,使用工厂的所有常见原因均适用。不同的服务实现可能需要非常不同的构造代码,并且使用工厂意味着注册表不需要知道实现细节,只需要指定服务行为所需的最低限度。

答案 1 :(得分:0)

我认为服务提供商接口的好处之一可能是松耦合,实际需要时,服务提供商实例与其消费者之间。