我在下面列出了“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();
}
}
提前致谢!!
答案 0 :(得分:0)
本案例中的提供者是工厂,使用工厂的所有常见原因均适用。不同的服务实现可能需要非常不同的构造代码,并且使用工厂意味着注册表不需要知道实现细节,只需要指定服务行为所需的最低限度。
答案 1 :(得分:0)
我认为服务提供商接口的好处之一可能是松耦合,实际需要时,服务提供商实例与其消费者之间。