设计模式32 - 服务定位器模式

作者: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
发布了61 篇原创文章 · 获赞 218 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_34139994/article/details/96590592
今日推荐