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. 当构造过程必须允许构 ...
随机推荐
- redis连接超时问题排查
连接池无法获取到连接或获取连接超时redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource f ...
- nvalid bound statement (not found)
问题详情: org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.coocaa.te ...
- <转> linux进程状态的说明
我只是做一个mark,为了日后复习:http://blog.csdn.net/tianlesoftware/article/details/6457487 他写得非常的详细,值得推荐. 补充一点什么是 ...
- j解决sparkr中使用某些r的原生函数 发生错误Error: class(objId) == "jobj" is not TRUE的问题
Create table function in Spark in R not working João_Andre (3) 询问的问题 | 2016年12月10日 06:03BLUEMIXRSPA ...
- SQLite 日期 & 时间
具体看http://www.runoob.com/sqlite/sqlite-date-time.html 不过实例介绍的不够详细,以下详细举例: SQLite包含了如下时间/日期函数:datetim ...
- paoding分词
Paoding 详细介绍 庖丁中文分词库是一个使用Java开发的,可结合到Lucene应用中的,为互联网.企业内部网使用的中文搜索引擎分词组件.Paoding填补了国内中文分词方面开源组件的空白,致力 ...
- getDimension()、getDimensionPixelOffset()和getDimensionPixelSize()区别详解
getDimension()是基于当前DisplayMetrics进行转换,获取指定资源id对应的尺寸.文档里并没说这里返回的就是像素,要注意这个函数的返回值是float,像素肯定是int. getD ...
- UPNP
基本概念 UPnP 的应用范围非常大,以致足够可以实现许多现成的.新的及令人兴奋的方案,包括家庭自动化.打印.图片处理.音频 / 视频娱乐.厨房设备.汽车网络和公共集会场所的类似网络.它可以充分发挥 ...
- 00-01.PHP 网站假设win7配置自己的IIS服务器亲自做的图文很详细 [转 - 赞 ]
win7配置自己的IIS服务器亲自做的图文很详细 分步阅读 跟人网站爱好初学者必看的win7系统配置自己的IIS,可以在你自己的电脑上配置网站服务器发不到网上,下面就跟着我的步骤一起做吧100%成功. ...
- 一个hadoop hdfs put 文件失败的小情况
/root/abc sudo -u hdfs hdfs dfs -put abc /user/larry 然而,提示“put: `abc': No such file or directory”. 一 ...