设计模式服务定位器模式

Posted guangze

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式服务定位器模式相关的知识,希望对你有一定的参考价值。

前言

本文介绍服务定位器模式(Service Locator Pattern),并提供了 UML 图和示例 Java 代码。

服务定位器模式

服务定位器模式实现了按需返回服务实例。在该模式中,应用所有需要的服务都会被注册到服务定位器中,并通过 ID 唯一标识。应用需要哪个服务,用这个 ID 就能从服务定位器中得到这个服务的实例。服务定位器模式解耦了服务调用者和具体的服务实现。该模式的 UML 类图可以表示如下:

技术图片

服务定位器模式包含如下组件:

  • Client:服务调用者,向服务定位器发出服务调用请求
  • Service Locator:客户端/服务端间通信入口,从 Cache 中返回服务
  • Cache:缓存、复用服务
  • Initializer:创建、注册服务到 Cache 中
  • Service:服务具体实现

Java 示例

让我们看一个具体的例子来理解服务定位器模式,准备代码如下:

// Java program to 
// illustrate Service Design Service 
// Locator Pattern 
  
import java.util.ArrayList; 
import java.util.List; 

首先,定义服务 Service 接口以及两个具体服务实现:

// Service interface 
// for getting name and 
// Executing it. 
  
interface Service { 
    public String getName(); 
    public void execute(); 
}

// Service one implementing Locator 
class ServiceOne implements Service { 
    public void execute() 
    { 
        System.out.println("Executing ServiceOne"); 
    } 
  
    @Override
    public String getName() 
    { 
        return "ServiceOne"; 
    } 
} 
  
// Service two implementing Locator 
class ServiceTwo implements Service { 
    public void execute() 
    { 
        System.out.println("Executing ServiceTwo"); 
    } 
  
    @Override
    public String getName() 
    { 
        return "ServiceTwo"; 
    } 
} 

接着定义 Service Locator 类,该服务器类实现了一个服务 Cache 以及一个服务实例返回函数 getService。getService 函数会优先返回缓存的服务实例,如果没有,则通过 Initializer 创建。

// Locator class 
class ServiceLocator { 
    private static Cache cache; 
  
    static
    { 
        cache = new Cache(); 
    } 
  
    public static Service getService(String name) 
    { 
        Service service = cache.getService(name); 
  
        if (service != null) { 
            return service; 
        } 
  
        InitialContext context = new InitialContext(); 
        Service ServiceOne = (Service)context.lookup(name); 
        cache.addService(ServiceOne); 
        return ServiceOne; 
    } 
} 

上面提到的 Cache 类和 Initializer 类具体实现如下:

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); 
        } 
    } 
} 

// Checking the context 
// for ServiceOne and ServiceTwo 
class InitialContext { 
    public Object lookup(String name) 
    { 
        if (name.equalsIgnoreCase("ServiceOne")) { 
            System.out.println("Creating a new ServiceOne object"); 
            return new ServiceOne(); 
        } 
        else if (name.equalsIgnoreCase("ServiceTwo")) { 
            System.out.println("Creating a new ServiceTwo object"); 
            return new ServiceTwo(); 
        } 
        return null; 
    } 
}

最后是 Client 类,测试代码效果:

// Client class 
class ServiceConsumer { 
    public static void main(String[] args) 
    { 
        Service service = ServiceLocator.getService("ServiceOne"); 
        service.execute(); 
  
        service = ServiceLocator.getService("ServiceTwo"); 
        service.execute(); 
  
        service = ServiceLocator.getService("ServiceOne"); 
        service.execute(); 
  
        service = ServiceLocator.getService("ServiceTwo"); 
        service.execute(); 
    } 
} 

输出结果:

Creating a new ServiceOne object
Executing ServiceOne
Creating a new ServiceTwo object
Executing ServiceTwo
Returning cached ServiceOne object
Executing ServiceOne
Returning cached ServiceTwo object
Executing ServiceTwo

总结

参考资料

[1] 30分钟学会UML类图
[2] Baeldung: Service Locator Pattern
[3] GeeksforGeeks: Service Locator Pattern

以上是关于设计模式服务定位器模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式服务定位器模式

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

你可以在graphql服务器模式文件中使用片段吗

服务定位器模式与抽象工厂模式有啥不同吗?

Unity设计模式—服务定位器模式

GoF--服务定位器模式