服务定位器模式(Service Locator Pattern)用在我们想使用 JNDI 查询定位各种服务的时候。考虑到为某个服务查找 JNDI 的代价很高,服务定位器模式充分利用了缓存技术。在首次请求某个服务时,服务定位器在 JNDI 中查找服务,并缓存该服务对象。当再次请求相同的服务时,服务定位器会在它的缓存中查找,这样可以在很大程度上提高应用程序的性能。以下是这种设计模式的实体。

  • 服务(Service) - 实际处理请求的服务。对这种服务的引用可以在 JNDI 服务器中查找到。
  • Context / 初始的 Context - JNDI Context 带有对要查找的服务的引用。
  • 服务定位器(Service Locator) - 服务定位器是通过 JNDI 查找和缓存服务来获取服务的单点接触。
  • 缓存(Cache) - 缓存存储服务的引用,以便复用它们。
  • 客户端(Client) - Client 是通过 ServiceLocator 调用服务的对象。

实现

我们将创建 ServiceLocatorInitialContextCacheService 作为表示实体的各种对象。Service1 和 Service2 表示实体服务。

ServiceLocatorPatternDemo,我们的演示类在这里是作为一个客户端,将使用 ServiceLocator 来演示服务定位器设计模式。

步骤 1

创建服务接口 Service。

Service.java

package gof.servicelocatorpattern;

public interface Service {

    String getName();
void execute();
}

步骤 2

创建实体服务。

Service1.java

package gof.servicelocatorpattern;

public class Service1 implements Service{

    @Override
public String getName() {
return "Service1";
} @Override
public void execute() {
System.out.println("Executing Service1");
} }

Service2.java

package gof.servicelocatorpattern;

public class Service2 implements Service{

    @Override
public String getName() {
return "Service2";
} @Override
public void execute() {
System.out.println("Executing Service2");
} }

步骤 3

为 JNDI 查询创建 InitialContext。

InitialContext.java

package gof.servicelocatorpattern;

public class InitialContext {

    public Object lookup(String jndiName){
if("SERVICE1".equalsIgnoreCase(jndiName)){
System.out.println("Looking up and Creating a new Service1 object");
return new Service1();
}else if("SERVICE2".equalsIgnoreCase(jndiName)){
System.out.println("Looking up and Creating a new Service2 object");
return new Service2();
}
return null;
}
}

步骤 4

创建缓存 Cache。

Cache.java

package gof.servicelocatorpattern;

import java.util.ArrayList;
import java.util.List; public class Cache { private List<Service> services; public Cache() {
super();
services = new ArrayList<Service>();
} public Service getServices(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 service){
boolean exists = false;
for(Service ser : services){
if(ser.getName().equalsIgnoreCase(service.getName())){
exists = true;
}
}
if(!exists){
services.add(service);
}
}
}

步骤 5

创建服务定位器。

ServiceLocator.java

package gof.servicelocatorpattern;

public class ServiceLocator {

    private static Cache cache;
static {
cache = new Cache();
}
public static Service getService(String jndiName){
Service service = cache.getServices(jndiName);
if(null != service){
return service;
}
InitialContext context = new InitialContext();
service = (Service) context.lookup(jndiName);
cache.addService(service);
return service;
}
}

步骤 6

使用 ServiceLocator 来演示服务定位器设计模式。

ServiceLocatorPatternDemo.java

package gof.servicelocatorpattern;

public class ServiceLocatorPatternDemo {

    public static void main(String[] args) {
Service service = null;
service = ServiceLocator.getService("Service1");
service.execute();
service = ServiceLocator.getService("Service2");
service.execute();
service = ServiceLocator.getService("Service1");
service.execute();
service = ServiceLocator.getService("Service2");
service.execute();
}
}

步骤 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

啦啦啦

GoF--服务定位器模式的更多相关文章

  1. Java服务定位器模式

    当我们想要使用JNDI查找来定位各种服务时,使用服务定位器设计模式. 考虑到为服务查找JNDI的高成本,所以在服务定位器模式使用缓存技术. 首次需要服务时,服务定位器在JNDI中查找并缓存服务对象. ...

  2. 避免在ASP.NET Core中使用服务定位器模式

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:服务定位器(Service Locator)作为一种反模式,一般情况下应该避免使用,在 ...

  3. Lind.DDD.IoC(大叔推荐)~在服务定位器中引入IoC容器~容器的适配器

    回到目录 关于依赖倒置(DIP) 高层模块不依赖于低层模块的实现,而低层模块依赖于高层模块定义的接口,通俗的讲,就是高层模块定义接口,低层模块负责实现,这在我们实际开发中经常被用到,层与层之间引用,经 ...

  4. 服务定位器(Service Locator)

    服务定位器(Service Locator) 跟DI容器类似,引入Service Locator目的也在于解耦.有许多成熟的设计模式也可用于解耦,但在Web应用上, Service Locator绝对 ...

  5. [WCF编程]13.并发:服务并发模式

    一.概述 传入的客户端调用消息会分发给Windows I/O线程池(线程默认为1000)上的服务实例.多个客户端可以发起多个并发的调用,并且服务可以在多个线程上处理这些请求.如果传入的调用分发给同一个 ...

  6. spring服务定位器类

    此文章是基于 搭建SpringMVC+Spring+Hibernate平台 功能:通过持有的Spring应用场景ApplicationContext,可在任何地方获取bean. 1. 服务定位器类:S ...

  7. YII框架的依赖注入容器与服务定位器简述

    依赖注入容器 依赖注入(Dependency Injection,DI)容器就是一个对象use yii\di\Container,它知道怎样初始化并配置对象及其依赖的所有对象. 依赖注入和服务定位器都 ...

  8. Docker Kubernetes Service 网络服务代理模式详解

    Docker Kubernetes  Service 网络服务代理模式详解 Service service是实现kubernetes网络通信的一个服务 主要功能:负载均衡.网络规则分布到具体pod 注 ...

  9. GOF对Builder模式的定义(转载)

    (1)意图 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. (2)适用性 1. 当创建复杂对象的算法应该独立于该对象的组成部分以及他们的装配方式:2. 当构造过程必须允许构 ...

随机推荐

  1. 稳定模式在RESTful架构中的应用

    本文由 ImportNew - 乔永琪 翻译自 javaworld.欢迎加入翻译小组.转载请见文末要求. 分布式系统中保持网络稳定的五种方式 重试模式 超时模式 断路器模式 握手模式 隔离壁模式 倘若 ...

  2. [hadoop读书笔记] 第十五章 sqoop1.4.6小实验 - 将mysq数据导入hive

    安装hive 1.下载hive-2.1.1(搭配hadoop版本为2.7.3) 2.解压到文件夹下 /wdcloud/app/hive-2.1.1 3.配置环境变量 4.在mysql上创建元数据库hi ...

  3. Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等

    方法一:(java习惯,在android不推荐使用) 刚刚开始接触android线程编程的时候,习惯好像java一样,试图用下面的代码解决问题 new Thread( new Runnable() { ...

  4. 如何在Windows 10安装和使用Linux的Bash shell

    转载自:百度经验 Windwos 10 的周年更新为开发人员提供一个大的新功能:一个完整的,基于Ubuntu的Bash shell中,可以直接在Windows上运行Linux软件. 这使得“Linux ...

  5. python进行数据分析------相关分析

    相关分析 import statsmodels.api as sm import pandas as pd import numpy as np from patsy.highlevel import ...

  6. 【转】【VS Code】配置文件Launch及快捷键

     Ctrl+shift+p,然后输入launch,点击第一个选项即可配置. 之后选择More即可 具体配置可修改为: { "version": "0.2.0", ...

  7. static为什么一般与final一起用?

    static和final的意义是不同的,static修饰的时候代表对象是静态的,而final修饰的时候代表对象只能赋值一次,他们连用的时候是因为定义的那个对象既要它是静态的,也要求它的值不能再被修改. ...

  8. CodeCombat森林关卡Python代码

    地牢关卡过完,接下来是边缘的森林! 1,森林保卫战 hero.moveUp() hero.buildXY("fence", 40, 52) hero.moveDown() hero ...

  9. 大数据:Spark Core(二)Driver上的Task的生成、分配、调度

    1. 什么是Task? 在前面的章节里描写叙述过几个角色,Driver(Client),Master,Worker(Executor),Driver会提交Application到Master进行Wor ...

  10. system.web下的HttpModules节点和system.webServer下的modules节点的配置区别

    [转]自定义HttpModule的一些经验--配置篇 自定义web模块,需继承System.Web.IHttpModule接口 一:拦截对该服务器所有的http请求. 第一步:将自定义module类使 ...