HiveMind介绍

<script type="text/javascript"> document.location.href="http://blog.csdn.net/mindhawk/archive/2006/12/16/1445004.aspx"; </script>  

介绍
HiveMind是一个服务(services)和配置(configuration)的微内核。


服务:HiveMind的服务由一系列容易访问和组合的普通Java对象组成(Plain Old Java Objects)。每一个服务最好用一个被它实现了的接口进行定义(但是HiveMind现在并不强制这点)。在需要的时候HiveMind会负责实例化每一个服务并且进行必要的配置。另外,HiveMind可以通过依赖注入让服务协同工作。
配置:HiveMind允许你为你的服务提供一个由你规定格式的复杂配置信息。同时,也可以将在不同模块里申明(contribution)的配置信息集中起来,并将它们全部转化为对象数据。在HiveMind的配置支持下,服务的体系结构可以和数据驱动的解决方案,完美的,有效的无缝结合。
微内核:HiveMind是一个用于创建应用程序的框架,而不是一个应用程序或应用服务器。HiveMind的“核心”是启动逻辑。它知道如何解析和理解模块部署描述符,并使用它们去实例化并初始化所有的服务和配置。

    在HiveMind里,一个服务是某个Java接口的实现。和其它框架,比如说SOAs(Service Oriented Architectures, 再比方SOAP或EJBs),不同的是HiveMind只关心组合处于同一个虚拟机上的Java代码。HiveMind通过描述符描述不同的服务、服务的生命周期和如何将服务组合在一起。HiveMind非常注意线程安全和单例服务对象的延迟创建。因此你不必在代码里面关心这些。
    HiveMind位于应用程序代码和低层J2EE或其它API之间。

    在这副图里面,应用程序访问了HiveMind的一个核心服务(用圆圈代表)。这些服务扮演着服务外观(facade)的角色;服务的实现依赖于其它很多服务和配置(用兰色方格代表)。服务的实现可以使用Java和J2EE的APIs, 甚至可以作为连接其它系统例如EJB session beans的“桥梁”。
    HiveMind的组织是围绕着模块实现的。模块是一个单独编译的单元,提供了一系列特定的服务和配置的申明。模块部署在它自身的JAR文件中,里面包含了描述符。运行时,不论这些服务是由HiveMind提供的还是由第三方包提供的,HiveMind都会把所有的模块和它们的描述符组合在一起,并将所有申明了的服务无缝的组合在一起。
    HiveMind的设计非常关注于J2EE。因为J2EE应用是多线程的,所以HiveMind的所有实现都是线程安全的。你的代码不用关注的太多,只要知道HiveMind实现了所有这些就够了。
    HiveMind允许你创建非常复杂的应用,而且使单独的部件(一个服务)简单并且可测试。HiveMind鼓励使用常用的最佳实现,比如说接口编程,问题分解,和保持代码不依赖于容器且高度可测试。
编码
    HiveMind设计的目的是使编码变得尽可能简洁和无痛苦。在根本上因为服务是处于同一个虚拟机的简单对象(POJOs--plain old java objects),J2EE里面所有复杂的地方都可以忽略,比方说没有了JNDI查找,没有了远程异常,没有了home和remote接口。当然,你仍然可以用HiveMind来处理EJBs。在这种这种情况下,服务将负责在请求EJB之前执行JNDI查找等(它们本身拥有很多数据)。
    在任何情况下,代码应该尽可能简短。外部对象代码(不由HiveMind管理的对象,像servlet)获取服务的方式就非常的自然。

Registry registry = RegistryBuilder.constructDefaultRegistry();
MyService service = (MyService)
registry.getService("com.mypackage.MyService", MyService.class);

service.perform(...);

你的代码需要负责的有:
  • 获取一个注册过的单例服务的引用li>
  • 知道获取服务的完整IDli>
  • 将接口类型做为参数传入
HiveMind需要负责的有:
  • 查找服务,在必要时创建服务
  • 检查服务类型和你代码里期望的类型
  • 执行严格的线程安全策略
  • 准确,详细的报告错误

注意:在一些特别的情况下,如果在整个注册器里只有一个服务实现了某个特定接口,那么你可以省略掉服务ID,比如getService(MyService.class)。


文档
    文档是HiveMind一个重要组成部分。一个内容全面的HiveMind应用程序文档,HiveDoc,可以在编译过程中自动生成。这个文档列出了所有的模块,所有的扩展点(包括服务和配置),所有的申明信息(服务的构造器,服务拦截器和配置内容)以及扩展点和它们的申明信息之间的交叉关联。
    模块和扩展点包含了注释信息,这些信息在文档自动生成时会配合生成工作。
    因为HiveMind是用一些很小的模块生成复杂的系统,所以HiveDoc就是为开发者提供的一个非常重要的工具。用它能和好的理解和调试程序。


使用HiveMind的原因
    和其它依赖注入框架类似,HiveMind的理念也是在减少应用程序代码量的同时是应用程序可测试。如果你的应用也像我处理的一样的话,会编写很多烦人的代码用于创建对象,组合并建立对象间的关系,读取处理配置信息等。


任务对比:记录方法进入和退出的日志
传统方法

public String myMethod(String param)

{

if (LOG.isDebugEnabled())

LOG.debug("myMethod(" + param + ")");


String result = // . . .


if (LOG.isDebugEnabled())

LOG.debug("myMethod() returns " + result);



return result;

}


     这个方法在函数有对个返回点时并不能很好的工作,并且还会在代码里添加很多分支。因此,会造成一些混乱。另外,它不能为方法中抛出的异常记录日志信息。


HiveMind方法
    让HiveMind为你的服务添加一个拦截器。拦截器将统一的为函数的进入退出和函数中抛出的异常记录日志信息。
    下面的描述符片段定义了一个服务。描述符不仅规定了服务的实现(使用<create-instance>标签),还为函数添加了一个拦截器(使用<interceptor>)。

<service-point id="MyService" interface="com.myco.MyServiceInterface">

<create-instance class="com.myco.impl.MyServiceImpl"/>

<interceptor service-id="hivemind.LoggingInterceptor"/>

</service-point>


任务对比:引用其它服务
传统方法

private SomeOtherService _otherService;


public String myMethod(String param)

{

if (_otherService == null)
_otherService = // Lookup other service . . .

_otherService.doSomething(. . .);



. . .

}


    如何查找其它服务会在应用运行环境中定义;可以通过JNDI查找一个EJB;像Avalon等其它的微内核框架会调用一个特殊的API。
    另外,这些代码不是线程安全的;对个线程可能同时执行,引起不期望的(甚至灾难性的)对其它服务的重复查找。


HiveMind方法
    让HiveMind帮你将其它服务作为一个属性插入。这就是依赖注入。HiveMind可以通过JavaBeans属性和构造方法参数的形式完成依赖注入。

private SomeOtherService _otherService;


public void setOtherService(SomeOtherService otherService)

{

_otherService = otherService;

}


public String myMethod(String param)

{

_otherService.doSomething(. . .);



. . .

}


    HiveMind使用代理机制来延迟服务的构造,直到真正需要时才会真正构造服务。赋给其它服务的代理对象会在服务方法第一次调用时构造实际的服务并对它进行配置工作。可喜的是这些都是在线程安全的前提下完成的。


任务对比:读取配置信息
传统方法
    找到一个资源文件或XML文件(在类路径还是文件系统?),读取它,然后编写代码解析原始数据并将它们转化为适当的Java对象。
    这种缺乏标准的方法会使数据驱动的解决方案变得非常麻烦而且不像预期的那样有价值,带来的往往是代码膨胀和缺乏灵活性。
    即便是使用XML文件进行配置,读取内容的代码也往往是低效的,缺乏测试的,并且缺少了HiveMind的错误检查能力。


HiveMind方法

private List _configuration;


public void setConfiguration(List configuration)

{

_configuration = configuration;

}


public void myMethod()

{

Iterator i = _configuration.iterator();

while (i.hasNext())

{

MyConfigItem item = (MyConfigItem)i.next();



item.doStuff(. . .);

}

}
    HiveMind能用配置扩展点的内容设置需要配置的属性。上例中list里的数据是从申明了的配置构造的,并由HiveMind转化为对象。和服务一样,配置也是线程安全的,延迟构造的。

 


任务对比:测试服务
传统方法
    使用像EJB容器这样的复杂环境,你必须首先部署你的代码然后在从外部测试它。EJB代码难于测试的原因就在于协同工作的EJBs需要使用JNDI去获取对方。如果只想测试应用程序局部的话就非常难办到了。


HiveMind方法
让代码可测试是HiveMind关注一个重点,在它的测试策略里面可以体现这一点。

  • 因为HiveMind服务是普通对象(POJOs),你的测试用例可以很容易的直接实例化它。
  • HiveMind服务是用接口来定义的,所以可以很容易的编写一个虚假的实现。
  • 服务的协同是通过依赖注入完成的,所以测试用例可以很容易的编写真实的或虚假的协同工作的服务实现。
  • 因为配置数据仅仅是Java对象的集合,所以测试用例可以很容易的编写一个适合于测试的对象集合。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值