作者:billy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
服务定位器模式
服务定位器模式(Service Locator Pattern)用在我们想使用 JNDI 查询定位各种服务的时候。考虑到为某个服务查找 JNDI 的代价很高,服务定位器模式充分利用了缓存技术。在首次请求某个服务时,服务定位器在 JNDI 中查找服务,并缓存该服务对象。当再次请求相同的服务时,服务定位器会在它的缓存中查找,这样可以在很大程度上提高应用程序的性能。以下是这种设计模式的实体。
- 服务(Service) - 实际处理请求的服务。对这种服务的引用可以在 JNDI 服务器中查找到。
- Context / 初始的 Context - JNDI Context 带有对要查找的服务的引用。
- 服务定位器(Service Locator) - 服务定位器是通过 JNDI 查找和缓存服务来获取服务的单点接触。
- 缓存(Cache) - 缓存存储服务的引用,以便复用它们。
- 客户端(Client) - Client 是通过 ServiceLocator 调用服务的对象。
UML结构图
代码实现
interface.h
创建抽象类 - 服务;创建子类 - 服务1、服务2
#include <string>
#include <iostream>
using namespace std;
class Service //基类-服务
{
public:
Service() {}
virtual ~Service() {}
virtual string getName() = 0;
virtual void execute() = 0;
};
class Service1: public Service //子类-服务1
{
public:
void execute()
{
cout << "Executing Service1" << endl;
}
string getName()
{
return "Service1";
}
};
class Service2: public Service //子类-服务2
{
public:
void execute()
{
cout << "Executing Service2" << endl;
}
string getName()
{
return "Service2";
}
};
cache.h
创建缓存
#include "interface.h"
#include <vector>
class Cache
{
public:
Service * getService(string serviceName)
{
for (auto it : services)
{
if ( serviceName == it->getName() )
{
cout << "Returning cached " + serviceName + " object" << endl;
return it;
}
}
cout << "No Service found in cache" << endl;
return nullptr;
}
void addService(Service *newService)
{
bool exists = false;
for (auto it : services)
{
if ( newService->getName() == it->getName() )
{
exists = true;
}
}
if(!exists)
{
services.push_back(newService);
}
}
private:
vector<Service *> services;
};
initialcontext.h
为 JNDI 查询创建 InitialContext
#include "interface.h"
class InitialContext
{
public:
Service * lookup(string jndiName)
{
if("Service1" == jndiName)
{
cout << "Looking up and creating a new Service1 object" << endl;
return new Service1();
}
else if ("Service2" == jndiName)
{
cout << "Looking up and creating a new Service2 object" << endl;
return new Service2();
}
cout << "Service init error" << endl;
return nullptr;
}
};
servicelocator.h
创建服务定位器
#include "cache.h"
#include "initialcontext.h"
class ServiceLocator
{
public:
static Service * getService(string jndiName)
{
Service *service = cache->getService(jndiName);
if (service != nullptr)
{
return service;
}
InitialContext *context = new InitialContext();
Service *service1 = context->lookup(jndiName);
cache->addService(service1);
return service1;
}
private:
static Cache *cache;
};
Cache * ServiceLocator::cache = new Cache();
main.cpp
实例应用 - 使用 ServiceLocator 来演示服务定位器设计模式
#include "servicelocator.h"
int main()
{
Service *service = ServiceLocator::getService("Service1");
service->execute();
cout << endl;
service = ServiceLocator::getService("Service2");
service->execute();
cout << endl;
service = ServiceLocator::getService("Service1");
service->execute();
cout << endl;
service = ServiceLocator::getService("Service2");
service->execute();
return 0;
}
运行结果:
No Service found in cache
Looking up and creating a new Service1 object
Executing Service1
No Service found in cache
Looking up and creating a new Service2 object
Executing Service2
Returning cached Service1 object
Executing Service1
Returning cached Service2 object
Executing Service2