使用依赖注入能够消除MovieLister对具体实现MovieFinder的依赖。这允许我把Movielister
但注入并不是解除依赖关系的唯一方法,还有一种方法也可以解除依赖关系,那就是使用服务定位器模式。
模式内容
服务定位器的最基本的思想就是有一个对象定位器知晓如何控制应用程序需要的所有服务。所以根据Lister&Finder例子提到的应用程序的一个服务定位器在需要的时候将会使用某个方法返回一个movie finder的实例。当然这仅仅是转移一些负担而已,我们仍旧必须取得进入lister的服务定位器,结果就呈现以下的依赖关系。
模式示例
MovieFinder finder = ServiceLocator.movieFinder();
class ServiceLocator...
public static MovieFinder movieFinder() {
return soleInstance.movieFinder;
}
private static ServiceLocator soleInstance;
private MovieFinder movieFinder;
就像注入方法一样,我们必须配置服务定位器(class ServiceLocator...)。下面我用代码来完成这个功能,但是使用从配置文件读取相应数据的机制也并不困难。
class Tester...
private void configure() {
ServiceLocator.load(new ServiceLocator(new ColonMovieFinder("movies1.txt")));
}
class ServiceLocator...
public static void load(ServiceLocator arg) {
soleInstance = arg;
}
public ServiceLocator(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
class Tester...
public void testSimple() {
configure();
MovieLister lister = new MovieLister();
Movie[] movies = lister.moviesDirectedBy("Sergio Leone");
assertEquals("Once Upon a Time in the Wes", movies[0].getTitle());
}
在对ServiceLocator的具体实现上还有很多技巧可以使用,
1.在初始化方式上,可以采用子类继承父类的方式,在父类初始化阶段 就得到 静态对象
2.还可以通过接口的方式返回一个movieFinder 这样 具体实现跟实际调用就通过接口隔离开了
3.还可以通过线程相关的存储机制来提供线程相关的定位器
4.还可以将几种movieFinder的实现,放入到Map中,动态的生成实例,以构建动态定位器
模式实现
import javax.naming.*;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import javax.ejb.EJBHome;
import javax.ejb.EJBLocalHome;
import javax.sql.DataSource;
import java.util.*;
import java.sql.*;
/** *//**
* 实现 service locater 模式,用于由客户端来调用以通过JNDI查
* 找相关的 ejb或是其它服务的入口.
* */
public final class ServiceLocater {
protected static ServiceLocater inst = new ServiceLocater();
private InitialContext ic = null;
private Map ejbHomeCache = null;
private Map dataSourceCache = null;
protected ServiceLocater() {
try {
dataSourceCache = Collections.synchronizedMap(new HashMap());
ejbHomeCache = Collections.synchronizedMap(new HashMap());
ic = new InitialContext();
}
catch (Exception e) {
e.printStackTrace();
}
}
/** *//**
* 取得 servicelocater的单子实例.
* */
synchronized public static ServiceLocater getInstance() {
return inst;
}
/** *//**
*查找并返回一个数据源
* @param name String 数据源名称
* @return DataSource ,查找不到则抛出异常.
* @throws NamingException ,查找不到或是类型不对。
* */
private DataSource lookUpDataSource(String name) throws NamingException {
DataSource tmpDS = (DataSource)this.dataSourceCache.get(name);
if (tmpDS == null) {
try {
tmpDS = (DataSource)this.ic.lookup(name);
this.dataSourceCache.put(name, tmpDS);
}
catch (NamingException namE) {
throw namE;
}
catch (Exception otherE) {
throw new NamingException(otherE.getMessage());
}
}
return tmpDS;
}
/** *//**
* 查找并返回一个远程接口
* @param jndiHomeName ebj名字
* @param className ejb类名字
* @return
* @throws ServiceLocatorException
*/
public EJBHome getRemoteHome(String jndiHomeName, Class className) throws
ServiceLocatorException {
EJBHome home = (EJBHome)this.ejbHomeCache.get(jndiHomeName);
if (home == null) {
try {
Object objref = ic.lookup(jndiHomeName);
Object obj = PortableRemoteObject.narrow(objref, className);
home = (EJBHome) obj;
this.ejbHomeCache.put(jndiHomeName, home);
}
catch (NamingException ne) {
throw new ServiceLocatorException(ne);
}
catch (Exception e) {
throw new ServiceLocatorException(e);
}
}
return home;
}
/** *//**
* 查找并返回一个本地接口
* @param jndiHomeName jndiHomeName名字
* @return 一个本地接口
* @throws ServiceLocatorException
*/
public EJBLocalHome getLocalHome(String jndiHomeName) throws
ServiceLocatorException {
EJBLocalHome home = null;
try {
home = (EJBLocalHome) ic.lookup(jndiHomeName);
}
catch (NamingException ne) {
throw new ServiceLocatorException(ne);
}
catch (Exception e) {
throw new ServiceLocatorException(e);
}
return home;
}
/** *//**
*查找一个数据源,并取得一个连接.
* @param name String 数据源名称
* @return DataSource ,查找不到则抛出异常.
* @throws NamingException ,查找不到或是类型不对。
* */
public Connection getConnection(String DataSourceJNDIName) throws
SQLException {
try {
Connection conn = this.lookUpDataSource(DataSourceJNDIName).getConnection();
conn.setAutoCommit(false);
//conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
return conn;
}
catch (Exception e) {
e.printStackTrace();
throw new SQLException(e.getMessage());
}
}
}
分享到:
相关推荐
.NET 服务器定位模式(Service Locator Pattern)——Common Service Locator-附件资源
服务定位器模式是软件设计模式之一,它提供了一种方式来查找和管理应用程序中的服务实例。本篇文章将深入探讨如何在Autofac中实现服务定位器模式,并且强调“零配置”的概念。 服务定位器模式是一种全局注册表,...
服务定位器模式(Service Locator Pattern)是一种软件设计模式,主要用于管理和服务对象之间的依赖关系。当应用需要查找并使用其他服务时,这种模式提供了一种集中管理和查找服务的方式。尤其是在Java开发环境中,...
安装labview之后,如何解决NI service locator is not running
在"11-ServiceLocator-Code.zip"压缩包中的"Code"文件,很可能包含了实现服务定位器模式的示例代码。通过对这些代码的分析,我们可以看到服务定位器是如何工作的,以及它与依赖注入的区别。通过学习这段代码,开发者...
Service Locator模式的基本思想是,维护一个全局的服务容器,其中存放了所有可用的服务实例。当需要使用某个服务时,只需从容器中查找即可,而无需直接依赖具体的服务实现。这样,我们可以在运行时动态地替换或注入...
Ckode.ServiceLocator Ckode.ServiceLocator是一个简单的本机实现的服务定位器,用于简化依赖项注入。 例子: 创建一个实例: var locator = new ServiceLocator();ISomeInterface instance = locator....
服务定位器(Service Locator)是一种全局性的依赖查找容器,它存储了应用中的各种服务实例,当需要某个服务时,可以通过服务定位器来获取。相比于传统的构造函数注入或setter注入,服务定位器在某些场景下可以提供...
在.NET开发环境中,服务定位器(Service Locator)是一种设计模式,用于在运行时查找和管理对象,特别是依赖注入(Dependency Injection, DI)的一种实现方式。本文将深入探讨ServiceLocator模式,以及它在.NET中的...
在PHP编程中,依赖注入(Dependency Injection,简称DI)和服务定位器(Service Locator,简称SL)是两种常见的设计模式,它们主要用于管理对象之间的依赖关系,以提高代码的可测试性、可维护性和松耦合性。...
本文中,作者深入探索IOC模式的工作原理,给它一个更能描述其特点的名字——“依赖注入”(Dependency Injection),并将其与“服务定位器”(Service Locator)模式作一个比较。不过,这两者之间的差异并不太重要,...
感谢菜鸟教程为我们大家做出的无私奉献。结合菜鸟教程实例,和Java设计模式(国外)...对设计模式进行自我学习。提供自我见解,源码文件。 希望有不好的地方多加理性批评,以便及时改正。
该文件解释了IServiceLocator实现必须正确实现以符合此接口的预期语义,以及一些实现注意事项。 规格 GetInstance(Type, string) 这是从容器中检索单个实例的核心方法。 此方法不得返回null。...
服务定位器 服务定位器违反了封装,隐藏了正确使用的前提条件。 是一种反模式。 是一种模式,允许我们开发松耦合代码。 结果 Get cached! services.Servicio1 Creating a new services.Servicio1 instance. Put ...
6. **服务定位器(Service Locator)**:Spring.NET的服务定位器模式可以方便地查找和管理服务,有助于实现解耦和模块化设计。 7. **企业服务支持**:Spring.NET还支持各种企业级服务,如邮件服务、任务调度、缓存...
参考Yii2实现的以依赖注入为基础的服务定位器,Yii2代码部分为vendor / yiisoft / yii2 / di /依赖注入DI依赖注入知道怎么初始化对象,只需配置构造参数就可以,核心代码如下(简化,只是说思路) class Di { //经过...
用Java实现23种设计模式 1. 创建型模式 工厂模式(Factory Pattern) ... 服务定位器模式(Service Locator Pattern) 传输对象模式(Transfer Object Pattern) 生产者消费者模式(Producer Consumer Pattern)