Java服务者提供者框架
2015-10-09 14:12
309 查看
《Effective Java》 第一条:考虑使用静态工程方法替代构造器 中提到使用静态工厂方式比构造函数方式更大的优势在于它们可以返回原返回类型的任何子类型的对象,其中一个非常好的应用就是服务提供者框架。服务提供者框架是指:多个服务提供者实现一个服务,系统为客户端提供多个实现,并把他们从多个实现中解耦出来。服务提供者的改变对它们的客户端是透明的,这样提供了更好的可扩展性。例如,JDBC,JMS等就是用了服务提供者框架。
下图以JDBC为例,做出的是他们之间的关联关系图
贴代码:
***************************************华美的分割线***************************************
下面为参考博文:http://liwenshui322.iteye.com/blog/1267202
1.服务具体实现类和服务提供者实现类是服务提供者自己去实现。以JDBC为例,这2个模块由具体的数据库提供商来实现。
2.其他三个模块是java对数据库提供商怎么实现上面2个模块的一个约束。比如:提供服务者实现类必须实现服务提供者接口。才能成功注册到服务提供者注册类。以JDBC为例,所有的数据库提供商只需要按照接口里面定义的规则来操作,都能成功地使java连上他们的数据库。
下面以mysql数据库为例简单说明一下mysql数据库提供商是如何实现这些接口的。
1.我们在java中获取mysql连接对象源代码如下:
从这个地方可以看出:我们只需要更换数据库的驱动名称与建立连接的URL,用户名等信息,就可以完全切换到另外一个数据库。数据库底部怎么操作的我们不清楚,也没必要清楚。我们获取的连接对象是Connection,查看java.sql.Connection这个类,会发现它只是一个接口。我们得到的只是一个接口,怎么可能能够操作数据库呢?其实这里得到的不是Connection接口,而是它的一个实现类,只是对于客户端不可见而已。这可能就是所谓的面向接口编程,客户端只需要知道它该知道的信息,服务端告诉客户端,你可以调用哪些方法。至于具体方法怎么实现是服务端的事情,客服端就不需要管,也不需要知道了。
下面我们看看简单的这2个语句分别做了什么事情:
语句一: Class.forName("...")。这样一个语句会实例化一个com.mysql.jdbc.Driver类(提供服务者实现类),并将这个类的实例注册到DriverManager(服务提供者注册类)。
语句二: 通过建立连接的URL,用户名,密码来获取建立到mysql数据库的连接。是这样的,DriverManager通过你传进来的url信息判断出你是要获取那个服务提供者提供的服务。也就是语句一已经将提供服务者实现类注册到DriverManager了,DriverManager获取到这个服务提供者实现类对象之后,通过调用它的getService(mysql里面是connect方法)方法获取到服务具体实现类对象,返回的却是java.sql.Connection接口对象(因为服务具体实现类实现了Connection接口),这样把服务具体实现类对象隐藏了。提供了很好的扩展性。
***************************************华美的分割线***************************************
其实也可以说我这篇是抄上面的吧,我只是想对这个加一些我对服务者框架的理解,哈哈。
下图以JDBC为例,做出的是他们之间的关联关系图
贴代码:
/** * $Author: ouyp $ * $Rev: $ * $Date:: 2015年10月9日#$: * @since CTP2.0 */ package com.effective; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class ServiceProviderFrameTest { public static void main(String[] args) throws Exception { // Class.forName("class com.effective.ServiceProviderFrameTest$SubwayProvideInterfaceImpl"); // Class c = SubwayProvideInterfaceImpl.class; //由于是内部类,我不知道用Class怎么加载,改为使用实例化的方式完成注册 SubwayProvideInterfaceImpl a = new SubwayProvideInterfaceImpl(); SubwayInterface subway = SubwayManager.getService("tft"); subway.in(); subway.out(); } //服务定义接口[java.sql.Connection] public static interface SubwayInterface { boolean in(); boolean out(); } //服务定义实现类[com.mysql.jdbc.ReplicationConnection] public static class TifuSubwayInterface implements SubwayInterface { @Override public boolean in() { System.out.println("使用天府通进入地铁站.."); return false; } @Override public boolean out() { System.out.println("使用天府通出地铁站.."); return false; } } //提供服务者接口[java.sql.Driver] public static interface SubwayProvideInterface { SubwayInterface getService(); } //提供服务者实现类[com.mysql.jdbc.Driver] public static class SubwayProvideInterfaceImpl implements SubwayProvideInterface { static { SubwayManager.register("tft", new Sub 4000 wayProvideInterfaceImpl()); } @Override public SubwayInterface getService() { return new TifuSubwayInterface(); } } //服务提供者注册类[java.sql.DriverManager] public static class SubwayManager { private final static Map<String, SubwayProvideInterface> registerMap = new ConcurrentHashMap<>(); public static void register(String key, SubwayProvideInterface sub) { registerMap.put(key, sub); } public static SubwayInterface getService(String key) { return registerMap.get(key).getService(); } } }
***************************************华美的分割线***************************************
下面为参考博文:http://liwenshui322.iteye.com/blog/1267202
1.服务具体实现类和服务提供者实现类是服务提供者自己去实现。以JDBC为例,这2个模块由具体的数据库提供商来实现。
2.其他三个模块是java对数据库提供商怎么实现上面2个模块的一个约束。比如:提供服务者实现类必须实现服务提供者接口。才能成功注册到服务提供者注册类。以JDBC为例,所有的数据库提供商只需要按照接口里面定义的规则来操作,都能成功地使java连上他们的数据库。
下面以mysql数据库为例简单说明一下mysql数据库提供商是如何实现这些接口的。
1.我们在java中获取mysql连接对象源代码如下:
Class.forName("com.mysql.jdbc.Driver"); DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","123");
从这个地方可以看出:我们只需要更换数据库的驱动名称与建立连接的URL,用户名等信息,就可以完全切换到另外一个数据库。数据库底部怎么操作的我们不清楚,也没必要清楚。我们获取的连接对象是Connection,查看java.sql.Connection这个类,会发现它只是一个接口。我们得到的只是一个接口,怎么可能能够操作数据库呢?其实这里得到的不是Connection接口,而是它的一个实现类,只是对于客户端不可见而已。这可能就是所谓的面向接口编程,客户端只需要知道它该知道的信息,服务端告诉客户端,你可以调用哪些方法。至于具体方法怎么实现是服务端的事情,客服端就不需要管,也不需要知道了。
下面我们看看简单的这2个语句分别做了什么事情:
语句一: Class.forName("...")。这样一个语句会实例化一个com.mysql.jdbc.Driver类(提供服务者实现类),并将这个类的实例注册到DriverManager(服务提供者注册类)。
语句二: 通过建立连接的URL,用户名,密码来获取建立到mysql数据库的连接。是这样的,DriverManager通过你传进来的url信息判断出你是要获取那个服务提供者提供的服务。也就是语句一已经将提供服务者实现类注册到DriverManager了,DriverManager获取到这个服务提供者实现类对象之后,通过调用它的getService(mysql里面是connect方法)方法获取到服务具体实现类对象,返回的却是java.sql.Connection接口对象(因为服务具体实现类实现了Connection接口),这样把服务具体实现类对象隐藏了。提供了很好的扩展性。
***************************************华美的分割线***************************************
其实也可以说我这篇是抄上面的吧,我只是想对这个加一些我对服务者框架的理解,哈哈。
相关文章推荐
- Java判断两个日期相差天数的方法
- Eclipse常用快捷键
- java将汉语转拼音
- Spring中的定时调度(Scheduling)和线程池(Thread Pooling)
- Struts2软件包的下载和配置
- java例子9 链表结构
- JavaSE8-The New Date and Time API(1)
- java.io.RandomAccessFile
- Java语言使用注解处理器生成代码 —— 第一部分:注解类型
- java - (08) JNDI
- javaweb文件下载
- Java基础:为何在JDK安装路径下存在两个JRE??
- 根据两点经纬坐标计算两点间的距离[JAVA]
- java并发编程学习: 守护线程(Daemon Thread)
- Struts2国际化其二
- 数据处理---Java数据处理之消息队列
- Java IO 之 FileInputStream & FileOutputStream源码分析
- 带哨兵的单链表的操作java版本
- java对象 深度克隆(不实现Cloneable接口)和浅度克隆
- 【转】Java基础:JDK JRE JVM三者之间的联系