程序员们有福了:独立于GUI的Java应用框架 Reflex 诞生了!

现在,大家用java开发最多、最火的应用是基于什么GUI?Andorid!应该没有人不知道!那你知道还有Awt、Swing、Swt、JavaFx吗?虽然它们主要是用于开发桌面应用的,不过也不全对,JavaFx也是可以导出为手机应用的。Whatever,不管它们面向什么平台,它们都是基于Java的 GUI的工具包或者框架,随着技术的发展,还会有越来越多的GUI工具会出现,这是一定的。难道我们这些程序员们就这么苦逼,每次的技术更新,我们都需要重新从0开始么?答案是NO!就像我们人类一样,虽然每个人都长得不一样,但是内部有一样的东西,使得我们可以思考、交流和行走。我们需要把GUI剥离,把那些永恒的东西进行提炼,这就是Reflex框架的目的。所以我说大家有福了,让我们抓住永恒和核心的东西,以不变应万变,这样,不管GUI再怎么变,都是so easy!

Reflex的中文意思是反射,整个框架是按照反射弧模式创建。没错,就是我们初中生物课本上学过的反射弧。大家如果有兴趣,可以去百度百科上温故而知新。我现在先简单说说它的结构,尽量不要陷入太多理论。为了大家有个直观认识,这篇文章主要还是以一个简单的Hello World 示例为主。

Reflex框架把一个应用程序分为5个部分:视图、感受器、业务中枢、数据模型、效应器。业务中枢就相当于业务层,数据模型就相当于数据层。框架独立于视图,我们平时的主要工作就是:

  1. 定义感受器来感知视图的行为。
  2. 感受器通知业务中枢,业务中枢改变数据模型或者协调各个业务中枢之间的关系。
  3. 定义效应器,绑定数据到指定视图。

从上面可知,只有感受器和效应器才和视图有关系,一个是监控视图行为、一个是为视图提供数据。为了和视图独立,我们通过Annotation来指定视图就行啦。

废话不再多说,以后有兴趣,大家可以慢慢了解。简单粗暴,上图先。

 

这个例子很简单,在视图上有两个元素,一个是按钮,一个是文本。操作是这样的:点击按钮,在业务中枢里面有个记数,每点一下,记数就增加1。文本显示的就是”Hello World”加上业务中枢中的记数。如下图:

可以看到,点击按钮,文本显示就自动更新。监控按钮点击的代码是这样:

@Receptor
public class BtReceptor {
    
    /**
     * 自动注入业务中枢 ,通过接口访问业务中枢
     */
    @Autowired
    private IHelloCenter helloCenter;
    
    /**
     * 感受对象是  id为bt的视图,行为刺激是: click 事件.
     * @param view
     */
    @Recept(target="bt", stimulation="android.view.View$OnClickListener")
    private void onRemoveBtClicked(View view)
    {
        helloCenter.changeCount();
    }
}

我们不需要手动创建感受器对象,在感受器类上用@Receptor标记,框架会在适当的时候自动创建该对象。onRemoveBtClicked方法上,有一个Recept注解,它定义了监听的视图和接口。视图和接口目前都是用字符串的形式表示,目的是 为了通用。在不同的gui框架里,需要不同的匹配算法来匹配视图。在android,这里的bt,就会自动匹配R.id.bt 这个按钮。至于接口,目前只支持写全接口,有点繁琐,是不是? 以后想办法解决。给定行为接口后,这个被注解的方法就相当于该接口的回调函数。在此例中,监控到按钮被点击后,就调用业务中枢的changeCount方法。

业务中枢因为@Autowired的关系,在BtReceptor被实例化的时候,会自动注入业务中枢对象。它的具体实现是这样:

@Center
public class HelloCenter extends BindableAware implements IHelloCenter,  Initializable {

    private int count = 0;
    
    @Override
    public void changeCount() {
        count ++;        
        invalidateBind("hello");
    }

    @Bindable(name="hello")
    @Override
    public int getCount() {
        return count;
    }

    @Override
    public void onInitialized() {
        
    }
}

功能上很简单,不多说,就是增加一个计数。需要说明的数据绑定,业务中枢需要继承BindableAware这个类,它有一个方法,invalidateBind。调用invalidateBind方法就可以通知外部,什么失效了。在此例中就是名为hello的数据绑定失效了,需要重新更新。而名为hello的数据绑定和getCount方法对应,也就是说getCount方法过时了。

比如效应器的代码就调用了getCount方法:

@Effector
public class TextEffector {

    /**
     * 自动注入业务中枢 ,通过接口访问业务中枢
     */
    @Autowired
    private IHelloCenter helloCenter;
        
    /**
     * 效应对象是  id为text的视图,效应方位是 text属性.
     * @param view
     */
    @Effect(target="text", site="text")
    public String getHelloText()
    {
        return "hello world " + helloCenter.getCount();
    }
}

此时框架会重新调用getHelloText方法,然后把结果赋予给R.id.text的视图,这样就完成了整个流程。例子程序完整代码在这里

其实,代码量不是很多,结构还很清晰,是不是很简单?简单归纳一下,Reflex为大家做了以下这些事情:

  1. 以Annotation的方式定义了和视图交互的方法,同时独立于视图。
  2. 把程序分为几个部分,每个部分都有自己专门职责,结构清晰。
  3. 自动数据绑定
  4. 业务对象自动注入。

好了,今天就简单说到这,Reflex现在还只是个雏形,离真正实用还有很大的距离,但是我会改进的。虽然这么说,但我个人力量有限,如果谁有兴趣一起进步,项目在这里,在此万分感谢。

原文地址:https://www.cnblogs.com/simplevita/p/4596340.html