服务定位器模式(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. wysiwyg加ckeditor加 代码高亮

    1.所需文件 drupal 版本:7.28 Wysiwyg- 7.x-2.2 (模块) 下载地址:http://drupal.org/project/wysiwyg Syntax Highlighte ...

  2. phpcms v9 所有当前栏目信息标签

    PHPCMS v9 很多时候在内容页下不关是调用内容页的信息,还会调用当前栏目的相关信息.下面做总结,方便大家找到在内容页想调用的东西当前栏目id:                       {$c ...

  3. Extjs4.x treegrid,check-tree,locked getChecked() 方法错误

    当在treegrid中,锁定treecolumn列的时候,是无法通过执行getView().getChecked()获取选中的节点的,这是tree的一个bug, 详见:http://www.sench ...

  4. servlet 过滤器实现 请求转发(跳转);跨域转发请求;tomcat 环境下。

    一般的文章都有 文本内容 和图片的.我想实现一个图片服务(或服务器)来单独处理图片逻辑,和文章处理逻辑分离.于是我想到一个办法,来尝试. 背景: 1. 假如文章的处理在web App,就叫web1 吧 ...

  5. 【C】——C语言字符串比较函数

    c语言字符串函数详解 void *memset(void *dest, int c, size_t count); 将dest前面count个字符置为字符c. 返回dest的值. void *memm ...

  6. 解决springmvc使用ResponseBody注解返回json中文乱码问题

    spring版本:4.2.5.RELEASE 查看“org.springframework.http.converter.StringHttpMessageConverter”源码,中有一段说明: B ...

  7. 《开发专家 Visual C 开发入行真功夫》笔记

    智能感知的功能,输入 is 后,同时按下Alt + →这两个键就出现了供选择变量.方法.宏等的列表,继续输入 in 后,isInit就出来了. stdafx.h预编译头文件,.h应用程序主头文件,do ...

  8. this小案例

    public class Son extends Parent { public String name="jack"; public void init(){ super.ini ...

  9. hibernate+pageBean实现分页dao层功能代码

    今天闲来无事,摆弄了一下分页,突然发现很多代码长时间不用就生梳了,虽然有些基础,但没有一篇整合的.这里还是简单示例,主要是以后自己翻着看不用百度找啊找找不到一篇想要的 1.PageBean实体类,一页 ...

  10. (笔记)Mysql命令drop database:删除数据库

    drop命令用于删除数据库. drop命令格式:drop database <数据库名>; 例如,删除名为 xhkdb的数据库:mysql> drop database xhkdb; ...