Design Pattern 简明教程
Design Pattern - Service Locator Pattern
在使用 JNDI 查找定位各种服务时,使用服务定位器设计模式。考虑到为服务查找 JNDI 的高成本,Service Locator 模式利用缓存技术。第一次需要服务时,Service Locator 会在 JNDI 中查找并缓存服务对象。通过 Service Locator 进一步查找或相同的服务在其缓存中进行,极大地提高了应用程序的性能。以下是这种设计模式的实体。
The service locator design pattern is used when we want to locate various services using JNDI lookup. Considering high cost of looking up JNDI for a service, Service Locator pattern makes use of caching technique. For the first time a service is required, Service Locator looks up in JNDI and caches the service object. Further lookup or same service via Service Locator is done in its cache which improves the performance of application to great extent. Following are the entities of this type of design pattern.
-
Service - Actual Service which will process the request. Reference of such service is to be looked upon in JNDI server.
-
Context / Initial Context - JNDI Context carries the reference to service used for lookup purpose.
-
Service Locator - Service Locator is a single point of contact to get services by JNDI lookup caching the services.
-
Cache - Cache to store references of services to reuse them
-
Client - Client is the object that invokes the services via ServiceLocator.
Implementation
我们将创建 ServiceLocator、InitialContext、Cache、Service 作为表示我们实体的不同对象。Service1 和 Service2 表示具体的服务。
We are going to create a ServiceLocator,InitialContext, Cache, Service as various objects representing our entities.Service1 and Service2 represent concrete services.
ServiceLocatorPatternDemo(我们的演示类)在此作为客户端,并使用 ServiceLocator 来演示服务定位器设计模式。
ServiceLocatorPatternDemo, our demo class, is acting as a client here and will use ServiceLocator to demonstrate Service Locator Design Pattern.
Step 1
创建服务接口。
Create Service interface.
Service.java
public interface Service {
public String getName();
public void execute();
}
Step 2
创建具体服务。
Create concrete services.
Service1.java
public class Service1 implements Service {
public void execute(){
System.out.println("Executing Service1");
}
@Override
public String getName() {
return "Service1";
}
}
Service2.java
public class Service2 implements Service {
public void execute(){
System.out.println("Executing Service2");
}
@Override
public String getName() {
return "Service2";
}
}
Step 3
为 JNDI 查找创建初始上下文
Create InitialContext for JNDI lookup
InitialContext.java
public class InitialContext {
public Object lookup(String jndiName){
if(jndiName.equalsIgnoreCase("SERVICE1")){
System.out.println("Looking up and creating a new Service1 object");
return new Service1();
}
else if (jndiName.equalsIgnoreCase("SERVICE2")){
System.out.println("Looking up and creating a new Service2 object");
return new Service2();
}
return null;
}
}
Step 4
创建缓存
Create Cache
Cache.java
import java.util.ArrayList;
import java.util.List;
public class Cache {
private List<Service> services;
public Cache(){
services = new ArrayList<Service>();
}
public Service getService(String serviceName){
for (Service service : services) {
if(service.getName().equalsIgnoreCase(serviceName)){
System.out.println("Returning cached " + serviceName + " object");
return service;
}
}
return null;
}
public void addService(Service newService){
boolean exists = false;
for (Service service : services) {
if(service.getName().equalsIgnoreCase(newService.getName())){
exists = true;
}
}
if(!exists){
services.add(newService);
}
}
}
Step 5
创建服务定位器
Create Service Locator
ServiceLocator.java
public class ServiceLocator {
private static Cache cache;
static {
cache = new Cache();
}
public static Service getService(String jndiName){
Service service = cache.getService(jndiName);
if(service != null){
return service;
}
InitialContext context = new InitialContext();
Service service1 = (Service)context.lookup(jndiName);
cache.addService(service1);
return service1;
}
}
Step 6
使用 ServiceLocator 演示服务定位器设计模式。
Use the ServiceLocator to demonstrate Service Locator Design Pattern.
ServiceLocatorPatternDemo.java
public class ServiceLocatorPatternDemo {
public static void main(String[] args) {
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();
}
}