GoF--服务定位器模式
服务定位器模式(Service Locator Pattern)用在我们想使用 JNDI 查询定位各种服务的时候。考虑到为某个服务查找 JNDI 的代价很高,服务定位器模式充分利用了缓存技术。在首次请求某个服务时,服务定位器在 JNDI 中查找服务,并缓存该服务对象。当再次请求相同的服务时,服务定位器会在它的缓存中查找,这样可以在很大程度上提高应用程序的性能。以下是这种设计模式的实体。
- 服务(Service) - 实际处理请求的服务。对这种服务的引用可以在 JNDI 服务器中查找到。
- Context / 初始的 Context - JNDI Context 带有对要查找的服务的引用。
- 服务定位器(Service Locator) - 服务定位器是通过 JNDI 查找和缓存服务来获取服务的单点接触。
- 缓存(Cache) - 缓存存储服务的引用,以便复用它们。
- 客户端(Client) - Client 是通过 ServiceLocator 调用服务的对象。
实现
我们将创建 ServiceLocator、InitialContext、Cache、Service 作为表示实体的各种对象。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--服务定位器模式的更多相关文章
- Java服务定位器模式
当我们想要使用JNDI查找来定位各种服务时,使用服务定位器设计模式. 考虑到为服务查找JNDI的高成本,所以在服务定位器模式使用缓存技术. 首次需要服务时,服务定位器在JNDI中查找并缓存服务对象. ...
- 避免在ASP.NET Core中使用服务定位器模式
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:服务定位器(Service Locator)作为一种反模式,一般情况下应该避免使用,在 ...
- Lind.DDD.IoC(大叔推荐)~在服务定位器中引入IoC容器~容器的适配器
回到目录 关于依赖倒置(DIP) 高层模块不依赖于低层模块的实现,而低层模块依赖于高层模块定义的接口,通俗的讲,就是高层模块定义接口,低层模块负责实现,这在我们实际开发中经常被用到,层与层之间引用,经 ...
- 服务定位器(Service Locator)
服务定位器(Service Locator) 跟DI容器类似,引入Service Locator目的也在于解耦.有许多成熟的设计模式也可用于解耦,但在Web应用上, Service Locator绝对 ...
- [WCF编程]13.并发:服务并发模式
一.概述 传入的客户端调用消息会分发给Windows I/O线程池(线程默认为1000)上的服务实例.多个客户端可以发起多个并发的调用,并且服务可以在多个线程上处理这些请求.如果传入的调用分发给同一个 ...
- spring服务定位器类
此文章是基于 搭建SpringMVC+Spring+Hibernate平台 功能:通过持有的Spring应用场景ApplicationContext,可在任何地方获取bean. 1. 服务定位器类:S ...
- YII框架的依赖注入容器与服务定位器简述
依赖注入容器 依赖注入(Dependency Injection,DI)容器就是一个对象use yii\di\Container,它知道怎样初始化并配置对象及其依赖的所有对象. 依赖注入和服务定位器都 ...
- Docker Kubernetes Service 网络服务代理模式详解
Docker Kubernetes Service 网络服务代理模式详解 Service service是实现kubernetes网络通信的一个服务 主要功能:负载均衡.网络规则分布到具体pod 注 ...
- GOF对Builder模式的定义(转载)
(1)意图 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. (2)适用性 1. 当创建复杂对象的算法应该独立于该对象的组成部分以及他们的装配方式:2. 当构造过程必须允许构 ...
随机推荐
- CubieTruck入手第一天
基本的參考资料整理例如以下: mod=viewthread&tid=160" id="thread_subject" style="word-wrap: ...
- Redis键
Redis的keys命令用于管理键.使用Redis的keys命令语法如下所示: 语法 redis 127.0.0.1:6379> COMMAND KEY_NAME 例子 redis 127.0. ...
- 构建Java并发模型框架
Java的多线程特性为构建高性能的应用提供了极大的方便,但是也带来了不少的麻烦.线程间同步.数据一致性等烦琐的问题需要细心的考虑,一不小心就会出现一些微妙的,难以调试的错误.另外,应用逻辑和线程逻辑纠 ...
- greendao数据库初次使用的配置及多表关联的初始化
1.在工程外层(Project)的build.gradle中添加依赖 buildscript { repositories { jcenter() } dependencies { classpath ...
- 安卓程序代写 网上程序代写[原]C语言基础
C 作者:han1202012 发表于2013-11-1 19:53:29 原文链接 阅读:28 评论:0 查看评论
- Jquery ThickBox的使用
thickbox是jQuery的一个插件,其作用是弹出对话框.网页框,使用户体验度更加愉悦,下面就来简单介绍它的几种用法.声明一下:这只是个人的总结记载而已.准备工作:你需要三个文件:thickbox ...
- js实例属性和原型属性
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <t ...
- Android Custom View系列《圆形菜单一》
前言 自定义view能够做出很多不同寻常的效果,圆形菜单交互效果不错,目前网上有两个版本,虽然比较庞大,但非常值得研究与学习. radial-menu-widget: https://code.goo ...
- Mxnet 查看模型params的网络结构
import mxnet as mx import pdb def load_checkpoint(): """ Load model checkpoint from f ...
- 嵌入式开发值zynq---zynq中tlv320aic23b spi的驱动移植
http://blog.csdn.net/djason43/article/details/52876742 http://blog.csdn.net/lxmky/article/details/68 ...