Service Locator Pattern,即服务定位模式,用于定位不同的服务。考虑到 InitialContext::lookup 的成本比较高,提供了 Cache 类缓存以定位到的服务。
代码实现
Service 接口
public interface Service { public String getName(); public void execute();
}
Service1, Service2 实现 Service 接口,提供具体服务
public class Service1 implements Service { private String name = "service1"; @Override
public String getName() {
return name;
} @Override
public void execute() {
System.out.println(name + "executing");
}
}
public class Service2 implements Service { private String name = "service2"; @Override
public String getName() {
return name;
} @Override
public void execute() {
System.out.println(name + " executing");
}
}
InitialContext 用于查找并初始化服务
public class InitialContext { public static Service lookup(String jndiName){ System.out.println(" initializing " + jndiName); if (jndiName.equals("service1")){
return new Service1();
}
else if(jndiName.equals("service2")){
return new Service2();
}
else{
System.out.println("cannot find " + jndiName);
} return null;
}
}
ServiceLocator 是在 InitialConext 之前的一个层,把已找到的服务缓存起来,避免重复创建服务。
public class ServiceLocator { private static Cache cache = new Cache(); public static Service getService(String serviceName){
Service service = cache.getService(serviceName); if (service == null){
service = InitialContext.lookup(serviceName);
cache.addService(service);
}
return service;
}
}
演示服务定位模式。
public class ServiceLocatorPatternDemo { public static void main() {
Service service = ServiceLocator.getService("service1");
service.execute(); service = ServiceLocator.getService("service2");
service.execute(); service = ServiceLocator.getService("service1");
service.execute(); service = ServiceLocator.getService("service2");
service.execute();
}
}
注:
为了简化模式关系演示,本案例没有处理找不到服务的情况,可以在 InitialContext::lookup 和 ServiceLocator::getService 方法声明爆出异常,交由客户端代码处理服务无法找到的情况。
参考资料