服务定位器模式
服务定位器模式(Service Locator Pattern)用在我们想使用 JNDI 查询定位各种服务的时候。考虑到为某个服务查找 JNDI 的代价很高,服务定位器模式充分利用了缓存技术。在首次请求某个服务时,服务定位器在 JNDI 中查找服务,并缓存该服务对象。当再次请求相同的服务时,服务定位器会在它的缓存中查找,这样可以在很大程度上提高应用程序的性能。以下是这种设计模式的实体。
- 服务(Service) - 实际处理请求的服务。对这种服务的引用可以在 JNDI 服务器中查找到。
- Context / 初始的 Context - JNDI Context 带有对要查找的服务的引用。
- 服务定位器(Service Locator) - 服务定位器是通过 JNDI 查找和缓存服务来获取服务的单点接触。
- 缓存(Cache) - 缓存存储服务的引用,以便复用它们。
- 客户端(Client) - Client 是通过 ServiceLocator 调用服务的对象。
实现
我们将创建 ServiceLocator、InitialContext、Cache、Service 作为表示实体的各种对象。Service1 和 Service2 表示实体服务。
ServiceLocatorPatternDemo,我们的演示类在这里是作为一个客户端,将使用 ServiceLocator 来演示服务定位器设计模式。

步骤 1-创建服务接口Service
Service.cs
namespace ServiceLocatorPattern
{
interface Service
{
string getName();
void execute();
}
}
步骤 2-创建实体服务
Service1.cs
using System;
namespace ServiceLocatorPattern
{
class Service1 : Service
{
public string getName()
{
return "Service1";
}
public void execute()
{
Console.WriteLine("Executing Service1");
}
}
}
Service2.cs
using System;
namespace ServiceLocatorPattern
{
class Service2 : Service
{
public string getName()
{
return "Service2";
}
public void execute()
{
Console.WriteLine("Executing Service2");
}
}
}
步骤 3-创建查询功能的InitialContext
InitialContext.cs
using System;
namespace ServiceLocatorPattern
{
class InitialContext
{
public object lookup(string jndiName)
{
if (jndiName.Equals("Service1"))
{
Console.WriteLine("Looking up and creating a new Service1 object");
return new Service1();
}
else if (jndiName.Equals("Service2"))
{
Console.WriteLine("Looking up and creating a new Service2 object");
return new Service2();
}
return null;
}
}
}
步骤 4-创建缓存Cache
Cache.cs
using System;
using System.Collections.Generic;
namespace ServiceLocatorPattern
{
class Cache
{
private List<Service> services;
public Cache()
{
services = new List<Service>();
}
public Service getServices(string serviceName)
{
foreach (var service in services)
{
if (service.getName().Equals(serviceName))
{
Console.WriteLine("Returning cached " + serviceName + "object");
return service;
}
}
return null;
}
public void addService(Service newService)
{
if (!services.Contains(newService))
{
services.Add(newService);
}
}
}
}
步骤 5-创建服务定位器
ServiceLocator.cs
namespace ServiceLocatorPattern
{
class ServiceLocator
{
private static Cache cache = new Cache();
public static Service getService(string jndiName)
{
Service service = cache.getServices(jndiName);
if (service != null)
return service;
InitialContext context = new InitialContext();
Service service1 = (Service)context.lookup(jndiName);
cache.addService(service1);
return service1;
}
}
}
步骤 6-使用ServiceLocator来演示
ServiceLocatorPatternDemo.cs
using System;
namespace ServiceLocatorPattern
{
class ServiceLocatorPatternDemo
{
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();
Console.Read();
}
}
}
步骤 7-验证输出
Looking up and creating a new Service1 object
Executing Service1
Looking up and creating a new Service2 object
Executing Service2
Returning cached Service1 object
Executing Service1
Returning cached Service2 object
Executing Service2