zoukankan      html  css  js  c++  java
  • 程序员们有福了:独立于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现在还只是个雏形,离真正实用还有很大的距离,但是我会改进的。虽然这么说,但我个人力量有限,如果谁有兴趣一起进步,项目在这里,在此万分感谢。

  • 相关阅读:
    docker tcp配置
    PostgreSQL 数据库备份
    docker 几种磁盘卷挂载方式的区别
    MAT
    OkHttp
    HashMap 在 Java1.7 与 1.8 中的区别
    【zabbix】zabbix 高可用架构的实现
    利用zabbix监控Vmware运行
    logback在SpringBoot下出现no applicable action for [appender], current ElementPath is
    NGUI:HUD Text(头顶伤害漂浮文字)
  • 原文地址:https://www.cnblogs.com/simplevita/p/4596340.html
Copyright © 2011-2022 走看看