@Catyee
2017-07-12T01:29:43.000000Z
字数 2676
阅读 561
Java 经验之谈 高效开发
对于一个类,要获得它的一个实例,一般而言是提供一个共有的构造器。但是可以考虑用一个静态工厂来代替构造器。要注意的是,这里的静态工厂与设计模式中的工厂方法不同。
来看一看服务提供者框架:
服务提供者框架是指这样一个系统:多个服务提供者实现了某个服务,系统为用户提供多个实现,并把它们从多个实现中解耦出来。
服务提供者框架中有三个重要的组件:服务接口(Service Interface), 这是由提供者定义和实现的。提供者注册API(Provider Registration API),这是系统用来注册提供者的,因为具体的服务由提供者实现,所以实际上只有注册提供者之后才会有具体的服务。服务访问API(Service Access API),是用户用来获取服务实例的。还有一个可选的组件:服务提供者接口(Service Provider Interface)
这些提供者负责创建其服务实现的实例。如果没有服务提供者接口,实现就按照类名称注册,并通过反射方式进行实例化。
举一个实例:
服务接口(Service Interface):
/*** Service Interface*/public interface Service {// Service-specific methods go here}
服务提供者接口(Service Provider Interface):
/*** 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 servicesprivate static final Map<String, Provider> providers = new ConcurrentHashMap<String, Provider>();public static final String DEFAULT_PROVIDER_NAME = "<def>";// Provider registration APIpublic static void registerDefaultProvider(Provider p) {registerProvider(DEFAULT_PROVIDER_NAME, p);}public static void registerProvider(String name, Provider p) {providers.put(name, p);}// Service access APIpublic 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();}}
这个类中包含提供者注册API和服务访问API。
最后是一个测试用例:
public class Test {//定义提供者,每一个提供者实现了一钟服务private static Provider DEFAULT_PROVIDER = new Provider() {public Service newService() {return new Service() {@Overridepublic String toString() {return "Default service";}};}};private static Provider COMP_PROVIDER = new Provider() {public Service newService() {return new Service() {@Overridepublic String toString() {return "Complementary service";}};}};private static Provider ARMED_PROVIDER = new Provider() {public Service newService() {return new Service() {@Overridepublic String toString() {return "Armed service";}};}};public static void main(String[] args) {// Providers would execute these lines//调用提供者注册API来注册提供者,注册完成之后,对应的提供者就会创建对应的服务Services.registerDefaultProvider(DEFAULT_PROVIDER);Services.registerProvider("comp", COMP_PROVIDER);Services.registerProvider("armed", ARMED_PROVIDER);// Clients would execute these lines//调用服务访问API来获得服务的实例Service s1 = Services.newInstance();Service s2 = Services.newInstance("comp");Service s3 = Services.newInstance("armed");System.out.printf("%s, %s, %s%n", s1, s2, s3);}}
理解:在测试用例中先定义一些提供者,之前说过服务是由提供者自己实现的,所以在定义这些提供者的时候要实现具体的服务。
在main函数中去真正使用服务的时候,首先要调用提供者注册API去对定义的提供者进行注册。注册完成之后才会有具体的服务。这个时候就可以通过服务访问API拿到某个提供者提供的具体服务了。
上面示例的运行结果:
Default service, Complementary service, Armed serviceProcess finished with exit code 0