第五种设计模式Service Locator
概述:其实对于我本人认为,这个设计模式不应该出现在SCWCD考试当中,出现在SCBCD考试更为合适。因为SCWCD侧重于web
module(JSP,Servlet,JavaBean),而SCBCD侧重于EJB module。这个设计模式也是对于EJB的JNDI查找而产生的。不过既然考试内容有,我们就来简单的接触一下吧。EJB的部分我不想说太多,但是需要我们知道的内容是,
EJB是部署在EJB容器(Jboss,Weblogic, Websphere等)里面的,而我们普通的JSP,Servlet,JavaBean是部署在Servlet容器(Tomcat,Resin等)里面。这样我们如果想在Servlet中访问EJB容器里面的组件,就需要一个本地的接口,我们通过调用这个本地接口的方法,来实现对于远程EJB组件的访问。这个本地接口可以知道到哪里去找EJB容器里面对应的对象(lookup操作)。所有的JavaEE都使用通用的JNDI作为查找方式,那么如果ServletA需要查找名字为”jimmy”这个服务,然后另外的一个servetB,servletC都需要查找同样的名字的服务的话。就需要做三个JNDI查找,如果同时有10个甚至上百个呢。这会影响到系统的性能,还会出现大量的重复代码。在这种情况下,可以考虑Service
Locator设计模式。
应用:小型的应用还是算了吧。只有在需要进行大规模的JNDI查找的时候才考虑。可以参考以下的结构图。

优点:可以把复杂的EJB, JNDI查找统一起来,规范成一个统一的接口来使用,既可以缓存查找结果,提高效率,还可以减少模块中的代码数量。更可以结合工厂模式,把复杂的问题抽象化。对于日后变化或者新增了业务模块,可以很方便的使用。减少了JNDI的查找,网络总体性能可以大幅度提高。
缺点:记得在复杂度还有效率之间寻找平衡点。
举例:当你的程序在到达业务层之前,如果需要大量的查找EJB组件的话,可以考虑使用这个模式。一个Service
Locator的客户端调用代码有可能是这样
public class ServiceLocatorTester {
public static void main( String[] args ) {
ServiceLocator serviceLocator =
ServiceLocator.getInstance(); // ServiceLocator是服务器端的Class name , getInstance()返回一个这个class的本身
try {
ProjectHome projectHome = (ProjectHome)
serviceLocator.getHome(
ServiceLocator.Services.PROJECT );//参考下面的服务器片断代码
}
catch( ServiceException ex ) {
// client handles exception
System.out.println( ex.getMessage( ));
}
}
}
//服务器片断代码
public EJBHome getHome( int s ) throws ServiceLocatorException {
EJBHome home = null;
try {
Context initial = new
InitialContext();
Object
bjref = initial.lookup(getServiceName(s));
Object bj = PortableRemoteObject.narrow(objref,
getServiceClass(s));
home = (EJBHome)obj;
}
catch( NamingException ex ) {
throw new ServiceLocatorException(...);
}
catch( Exception ex ) {
throw new ServiceLocatorException(...);
}
return home;
}
我们不是教你EJB,我们只是需要pass考试,这部分不必要过于重点了解。
考试:记住以下的要点,有助于通过考试。
Abstracts Complexity.
Provides Uniform. Service Access
to Clients
Facilitates Adding New Business
Components
Improves Network Performance
Improves Client Performance by
Caching
Reduce line of codes
in application.