使用JIOPi构建工业化模型的Java模块系统系列文章之二
模块化系统的设计起点——控制面板
随着编程语言的进步,系统的描绘方法也发生着进化,随着面向对象编程的OO时代的进入,出现了若干系统构建和描述方法,如目前最流行的UML统一建模语言
对于模块化系统来说,设计可能将分为两个环节,系统设计和模块实现设计,模块的内部实现可能还是应当遵循面向对象的设计方式,而系统设计则可能会有所不同。
就如同 工业化产品一样,模块化系统也可以很容易的更换掉一个实现模块,而这点依赖于良好的模块化系统的设计,在系统设计阶段,不会有实现类出现,就如同工业化产品的图纸(Blueprint,蓝图)一样,模块化的软件系统设计可能也可以使用图纸来进行描绘,并且最外层的装配图纸可能是非常简单的,就像PC系统,最外层的装配图就是将若干模块与主板相连。
也就是说,一个复杂的模块化系统,可能具有多级层次,一个系统是由若干模块相连而成,这是最外层,在这一层次的蓝图设计中,只会定义该层次各个模块的用途的接口方式。而再进入到这其中的一个模块中的时候,一个模块的蓝图设计可能又是由若干模块相连而成,但这一层次的设计是不会出现在最外层的图纸中的。那么模块与模块是如何相连的呢?是通过控制面板(ControlPanel)。
这就是JIOPi的模块化系统中,除了蓝图,模块以外,另一个非常重要的概念——控制面板。
那么什么是控制面板呢?
控制面板一词来源于工业化系统,用Java语言来说,就是interface,在IoC体系中,对类对象的访问是通过interface来操作的,对模块的访问当然也是。那么为什么不叫interface而叫 ControlPanel呢?因为用于描绘JIOPi蓝图的Java程序并不限制为interface,为了避免语义混淆,而改名为ControlPanel。
对于模块化系统而言,要访问一个模块,是无需了解实现类细节的,而唯一需要了解的就是这个模块的蓝图提供了哪些控制面板。对模块的使用,也是从 控制面板开始的。因此一个模块的设计,也就是从 设计控制面板开始的。
下面,我就以设计一个假想的简单汽车模型为例来说明JIOPi模块化系统的设计和开发过程。
汽车是一个模块蓝图,因此要先绘制汽车的蓝图,为了简单,我只让这个汽车可以开动 start(), 停止 stop(), 以及获取汽车当前状态getStatus(),功能比较简单,因此可以封装在一个 控制面板 之上,代码如下:
package star.trek.voyager.blueprint.car;
import org.jiopi.framework.annotation.blueprint.RegisterControlPanel;
@RegisterControlPanel("voyager.car")
@Version
public interface Car {
public void start();
public void stop();
public String getStatus();
}
为了方便对控制面板的访问简化,使用了 @RegisterControlPanel("voyager.car") 将 star.trek.voyager.blueprint.car.Car 这个控制面板名 注册为短名称 voyager.car,只有一个用途,就是在以后访问时(特别是在配置文件中),只用写短名称就行了,如果觉得没必要可以不添加这个标注。
@Version标注上定义了这个蓝图的name,version,versionInterface属性,源码在源码下载包中的ibean-example目录。
看到这个类,相信大家都知道这个蓝图能怎么用了,我们下面就先来看看 在JIOPi容器中,如何使用这个蓝图。
这里我假设你已经在你的项目的lib中放了iBean的实现容器,如果还没有,请去http://code.google.com/p/ibean/downloads/list 下载,如果你准备使用本地安装模式,请额外下载JIOPi-iBean-0.3.0.0 patch 1,补丁说明请参阅 http://www.jiopi.org/blog/?p=44
在传统编程模式下,如果要用这个接口,我想你一定会问我要实现类的下载地址,以及实现类应当如何使用,比如是new 还是 用哪个工厂方法,是否需要修改什么配置文件?
在 JIOPi 的模块化系统中,这些都不复存在了(不是没有,是你可以忽略)。下面我们就来看一段 JIOPi所见即所得的代码:
import org.jiopi.framework.CentralConsole;
import org.jiopi.framework.FrameworkInitializer;
import org.jiopi.framework.ModuleConsole;
import org.jiopi.framework.ControlPanel;
public class CarTest {
public static void main(String[] args) {
FrameworkInitializer.initialize();
ModuleConsole car = CentralConsole.accessModuleConsole("voyager.benz.car_sls_amg", "0.1.0.0");
ControlPanel benzSlsAmg = car.accessControlPanel("voyager.car", ControlPanel.class);
System.out.println(benzSlsAmg.operate("getStatus", String.class));
}
}
你可以直接将该代码复制到你的IDE中运行。
从代码中可以看到,我使用了一个叫做 voyager.benz.car_sls_amg 的模块,版本限定为0.1.0.0
使用accessControlPanel获取到该模块的 voyager.car 控制面板(也就是我们前面定义的那个),
然后运行 getStatus方法
这就是 JIOPi 模块化系统的 实现类细节忽略,要使用一个模块,首先需要知道这个模块的蓝图中定义的控制面板,然后获取控制面板进行访问。
为了使用Java风格的调用,你可以在你的lib中安装Car的控制面板(帖子后面有下载),于是代码变为
import org.jiopi.framework.CentralConsole;
import org.jiopi.framework.FrameworkInitializer;
import org.jiopi.framework.ModuleConsole;
import star.trek.voyager.blueprint.car.Car;
public class CarTest2 {
public static void main(String[] args) {
FrameworkInitializer.initialize();
ModuleConsole car = CentralConsole.accessModuleConsole("voyager.benz.car_sls_amg", "0.1.0.0");
Car benzSlsAmg = car.accessControlPanel("voyager.car", Car.class);
System.out.println(benzSlsAmg.getStatus());
}
}
当然,你可以使用其他Ioc框架注入 Car对象而避免在代码中出现JIOPi的API,参见 http://jiopi.iteye.com/blog/656101
当然,你也可以很方便的更换其他实现模块,将voyager.benz.car_sls_amg替换为其他模块的名字即可。
控制面板的概念就介绍到这里,稍后介绍 voyager.benz.car_sls_amg 的实现,一个完整的模块化系统的实现。