引入:静态工厂方法返回的对象所属的类,在编写包含该静态工厂方法的类时可以并不存在,这种灵活的静态工厂方法构成了服务提供者框架的基础。——引自effectivejava
服务提供者框架中有三个重要组件:服务接口(Service Interface),由服务提供者实现;提供者注册API(Provider Registration API),这是系统用来注册实现,让客户端访问他们的;服务访问API(Service Access API),是客户端用来获取服务的实例的。
服务提供者框架的第四个组件是可选的:服务提供者接口(ServiceProviderInterface),这些提供者负责创建其服务实现的实例。如果没有服务提供者接口,实现就按照类名称注册,并通过反射方式进行实例化。--转
看似简单,不仔细想想也是不行的。服务提供者框架,我理解涉及到三方面角色,一个是系统服务,他只负责提供服务,却不提供具体的实现,比如交通部门,负责提供交通运输,但是他自己不提供具体的实现。具体服务的实现是其下层,提供者角色。他组要是提供具体的服务,而不对外公布其细节处理。第三个角色就是使用者,即客户端访问。根据客户端的不同需求,调用系统服务,系统服务交给具体的实现商实现。
框架的优势在于为提供商制定统一的接口规范,使其隐藏具体的实现细节。为客户端提供统一的访问接口,并根据需要灵活的切换不同的实现者。
系统服务
系统服务需要兼顾提供者和使用者,并且实现解耦。
对于供应商,系统可以定义好接口规范以供实现【服务提供者接口】:
package com.cs.aine.service;
public interface Provider {
public Service getService();
}
提供接口之后,必须接受供应商的注册,不然供应商无法植入到系统服务中来【提供者注册API】:
package com.cs.aine.service;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class ServiceManager {
public ServiceManager() {
}
private static final Map<String, Provider> providers = new ConcurrentHashMap<String, Provider>();
/**
* @desc for provide to register provider
* @param name
* @param p
*/
public static void registerProvider(String name, Provider p) {
providers.put(name, p);
}
对于使用者,系统服务必须定义好统一的访问接口,这定义了系统具体提供了哪些服务【服务接口】:
package com.cs.aine.service;
/**
*
* @author Aine
*
*/
public interface Service {
public void goDanYang();//系统提供了去丹阳的功能
public String getFood();//系统提供了获取食物的功能
}
除此之外,系统服务必须公开访问服务的接口,否则客户端无法获取服务【服务访问API】:
package com.cs.aine.service;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class ServiceManager {
public ServiceManager() {
}
private static final Map<String, Provider> providers = new ConcurrentHashMap<String, Provider>();
/**
* @desc for client to get service
* @param name
* @return
*/
public static Service getService(String name) {
Provider p = providers.get(name);
if (p == null) {
throw new IllegalArgumentException(
"No provider registered with name:" + name);
}
return p.getService();
}
}
提供者/供应商
提供者需要做两个事情:
1 实现系统服务的提供者接口,将自己注册到系统中去。
2 实现系统服务的服务接口,提供自己的实现,并且隐藏在框架之外,不对外公开
package com.cs.aine.provide;
import com.cs.aine.service.Provider;
import com.cs.aine.service.Service;
import com.cs.aine.service.ServiceManager;
public class BusService implements Provider{
static {
ServiceManager.registerProvider("Bus", new BusService());
}
@Override
public Service getService() {
return new SerciceImpl();
}
/**
*
* @author Aine
* @desc needn't internal class
*/
class SerciceImpl implements Service{
@Override
public void goDanYang() {
System.out.println("haha, I'm Bus service. I can bring you to DanYang.");
}
@Override
public String getFood() {
System.out.println("haha, I'm Bus service. I can supply you bus food.");
return "Bus Food";
}
}
}
客户端
客户端根据自己的需求,选择不同的服务实现者,比如去丹阳,你自己要选择好做什么交通工具,可以坐汽车,可以做火车,也可以做轮船等等,这都是客户端的事情。
package com.cs.aine.client;
import com.cs.aine.service.Service;
import com.cs.aine.service.ServiceManager;
public class ClientTest {
public static void main(String [] args){
try {
Class.forName("com.cs.aine.provide.TrainService");
Service service = ServiceManager.getService("Train");
service.goDanYang();
String food = service.getFood();
System.out.println("I hava food:"+food);
Class.forName("com.cs.aine.provide.BusService");
service = ServiceManager.getService("Bus");
service.goDanYang();
food = service.getFood();
System.out.println("I hava food:"+food);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
运行结果
haha, I'm Train service. I can bring you to DanYang.
haha, I'm Train service. I can supply you train food.
I hava food:Train Food
haha, I'm Bus service. I can bring you to DanYang.
haha, I'm Bus service. I can supply you bus food.
I hava food:Bus Food
思考和讨论
1 在客户端必须要知道自己选择的服务提供商的java实现类必须有供应商的驱动包。
客户端实例化的时候才会驱动注册服务,是否可以将注册服务依附在系统服务中,客户端就可以从服务框架中选择服务商了。
2 如何让框架提供default的实现。
分享到:
相关推荐
《Effective Java》第三版中文版目录 第一章 介绍 1 第二章 创建和销毁对象 4 1 考虑用静态工厂方法替换构造器 4 2 当遇到多个构造器参
effective-java.pdf
Effective Java读书笔记.pdf
Effective java 3 学习记录
effective java 读书笔记,第二版自己摘要并翻译,以备速查。
Effective Java读书笔记,记载了大部分我觉的有用的东西,前半部分有代码说明,但后半部分的代码,太过琐碎,就没有整理
【Effective Java】阅读笔记markdown 文件
《Effective Java》读书分享.pptx
15. 使类和成员的可访问性最小化 16. 在公有类中使用访问方法而非公有域 17.使可变性最小化:不可变类
effective-java 配套代码
Effective Java Effective Java Effective Java
无论你是否是Java开发人员,本书都将为你开发高效的企业系统提供诸多帮助。“通过这本书,TedNeward将帮助你实现从一个优秀的Java企业应用开发者向一个伟大的开发者的飞跃!” ——John Croupi, Sun著名工程师,...
Effective Enterprise Java
effectiveJava的笔记
我尽我最大的可能为大家提供了一个最佳实践 —— 《effective java》 第三版。我希望第三版继续满足需求,同时继承前两版的精神。 Small is beautiful, but simple ain’t easy 。 蓝领不是贬低的意思,主要是 ...
java四大名著之一:Effective.Enterprise.Java.中文版 高清pdf 下载
分享effectiveenterprisejava中文版
effective java,英文第三版,内容不错,有需要可以下载