1. 概述

长久以来,在Web编程中,一直很难克服的一个问题就是:展现层与业务数据纠缠在一起,无法进行良好的解耦, 从而造成应用系统的扩展性差,维护成本高。于是,出现了所谓的MVC框架,试图以 Model-View-Control 这种非常流行的设计模式,将两者有效的隔离开来。但回顾目前主流的 Web MVC 架构,它们所做的绝大部分工作无非是:将页面中控件的值取出打包成 Java Bean;再无非就是在帮助你完成页面导航的过程中,辅助你进行页面参数的传递与分析。这样一种“简单 MVC”架构,是无法完全解决“展现层与业务数据完全解耦”这个问题的。 一旦你的需求超越了框架的能力,那么,你将面对的依然是:不得不在展现层中嵌入大量的 Script 代码,可能是Java代码片断,也可能是大量tag-lib及EL表达式的引入。

 

2. 什么是IoVC

IoVC——“Inversion of View-Control”,即“视图控制反转”,换言之:它能够把对“View(即 UI 视图)的控制力”注入到你的后台业务逻辑中。这样一来,你在编写业务逻辑的过程中,对 View 拥有足够的控制力,从而能够将展现层与业务逻辑完全的解耦。

 

举一个场景:页面中有一个文本输入框,它的值对应后台的一个JavaBean的属性。我们首先来看一下传统的编程模型:

 

页面:
<w:textField value="#{myBean.value}"/>
后台:
public class MyBean {
    private String value;
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
}

 

此时,假设用户需要发生变化,我们需要设置文本输入框的tooltip,并且,它的值来自于后台 JavaBean 的另一个属性,那么,程序需要做如下调整:

 

页面:
<w:textField  value="#{myBean.value}" tooltip="#{myBean.tooltip}"/>
后台:
public class MyBean {
    private String value;
    private String tooltip;
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }    public String getTooltip() {
        return tooltip;
    }
    public void setTooltip(String tooltip) {
        this.tooltip = tooltip;
    }
}

 

我们可以观察:在传统的编程模型下,如果页面逻辑发生变化,我们首先需要修改UI展现层,加上 tooltip="#{myBean.tooltip}" 的语句,然后,再在后台Bean中设置此属性值。

那么,在IoVC编程模型下,情况又是怎样的呢?

 

页面:
<w:textField id="txt"/>
后台:
public class MyBean {
    @Bind(id="txt")
    private String value;
}

 

如果需要扩展文本编辑框的tooltip属性,只需要:

 

页面:
<w:textField id="txt"/>
后台:
public class MyBean {
    @Bind(id="txt")
    private String value;

        @Bind(id="txt" att="tooltip")
    private String tooltip;
}

 

在IoVC编程模型下,Web页面不需要发生任何变化,你只需要在后台 Java Bean 中写上这样一行属性声明即可@Bind(id="txt" att="tooltip") private String tooltip,甚至于你连传统的getter/setter都不需要。

 

换言之,在传统的编程模型下,页面美工通过网页设计工具“画”出来的页面,程序员看不懂; 而如果程序员对页面进行修改,则页面美工又无法理解; 并且,如果要更改业务逻辑,程序员需要不断的维护页面内容,最终造成页面美工与程序员无法协同工作。而在 IoVC 的编程思想下,页面美工只需要给每个组件设置一个ID,程序员在后台的业务逻辑中,便拥有对页面 UI 元素的完全控制力。Web页面在美工完成之后,程序员再也无需因为需求的变更或者逻辑的变化,而再重新维护 Web页面内容。

 

简而言之,IoVC是一种更好的MVC,是对MVC的一种高层次抽象。

 

设想一下:日后美工人员画出来的页面(只要设置了正确的ID),程序员可以拿过来直接用,并且, 如果要对页面做调整(只要不是页面元素的增加或删除),程序员可以在自己熟悉的代码中直接设置,这岂非是一种很享受的境界?

 

更多技术文章,请见:http://www.operamasks.org/

 

评论
aah_aah 2008-04-05
hax 写道
关于elite,我只是说它的介绍自相矛盾。我并没有说elite本身好或不好,语言这个领域我不是专家,如果要有人来评判,或许ajoo可以。


如你所说,你根本就不懂,就捡着人家一句两句话,便极尽挖苦嘲讽之能事,这样的“评判”有何意义?
hax 2008-04-04
关于elite,我只是说它的介绍自相矛盾。我并没有说elite本身好或不好,语言这个领域我不是专家,如果要有人来评判,或许ajoo可以。
hax 2008-04-04
aah_aah 写道
hax,你知道人家说的elite是干什么用的吗?在aom中,你甚至可以完全抛开Java用elite做一个程序。
按照人家的说法,你可以在后台用elite(当然也可以集成java)调用业务逻辑,也可以通过IoVC影响UI,这怎么又自相矛盾了呢?
要想批评人家,就不妨把人家做的东西全盘理解透彻了以后再说,否则,一叶障目,不见泰山,一知半解的情况下就大肆嘲讽,说什么“糟蹋JSF”诸如此类的言语,你不觉得惭愧吗?

我承认,我是和AOM有点关系,我是他们的用户,他们曾经给我们公司进行过AOM的培训。
思想不思想的我不想谈,至少我认为,AOM给我带来了开发效率的提升,仅评这一点,至少我很满足。

扯吧扯吧,跟一个满口'丫丫'的人,有什么道理可讲?



有些人总以为别人什么都不知道。你看懂我批评什么了吗?

还有,你看不出自相矛盾在哪里?那好,你再好好看看吧。很简单的。就那么几行字而已。

还有恭喜AOM有你这样好糊弄的客户。

还有,我看别人说话,是看他说的有没有道理,而不会管他说了几个脏字,何况“丫”字还够不上脏字,只不过是一种修辞手法而已。
aah_aah 2008-04-04
同时,对aom的人也想说两句:
1)质量要迅速稳定,我们已经不需要什么新特性了。
2)案例和文档要丰富,别总是那几个简单的例子,以让别人说闲话。

祝aom一路走好!
aah_aah 2008-04-04
hax 写道

不看不知道,一看吓一跳。AOM专做反其道行之的事情。

我现在很同情JSF了,被AOM这样糟尽。。。

BTW我摘录的是第一段和最后一段。大家可以发现其中的自相矛盾之处吗?


“OperaMasks已经在JSR-252的基础上对表达式语言做了大量的扩充,已经成为一种全新的表达式语言,我们将其命名为ELite,意为其源于EL表达式,同时又有轻量(Lite)的含义。

在OperaMasks的IoVC框架之下,EL已经很少出现在视图中,而在业务层将更多地使用EL来简化业务模型的开发,例如注入依赖对象、发送模型事件等。因此,JSR-252所定义的表达式语言已经不能满足要求,我们必须设计一种功能更强大的表达式语言来灵活地访问和操纵业务模型对象。
……
到现在为止,您还认为ELite是一种简单的表达式语言吗? ELite现在已经演化成为一个功能强大的动态语言,它脱胎于LISP这门古老而伟大的语言,同时又具有与Java相近的语法形式,可以容易地调用Java所写的程序代码,以及提供了方便灵活的集合操作函数,使其成为编写展现层逻辑的一种奇妙的选择。”

看到Elite,我想到了JS。因为Elite又是一种胶合语言,起的作用和JS如出一辙。只不过Elite在服务器端,而JS在浏览器端。

早晚(就2、3年最多了)会发展出强大的B端组件模型(ext就是明证),而加上DWR/Sajax这样的模式之后,抛开皮相的差别,编程模式最终还是归于一统。

唯一差别是多少在Browser,多少在Server而已。AOM说我能把Server端的逻辑靠ajax搬点到Browser上,但是大家自己直接用DWR不行吗?唯一的优势或许是Elite语言比JS好一点?不过这点优势实在是太不堪一击了。

如果有人要扯IDE支持、JSF组件模型优势……那就扯吧,反正扯扯无伤大雅。



hax,你知道人家说的elite是干什么用的吗?在aom中,你甚至可以完全抛开Java用elite做一个程序。
按照人家的说法,你可以在后台用elite(当然也可以集成java)调用业务逻辑,也可以通过IoVC影响UI,这怎么又自相矛盾了呢?
要想批评人家,就不妨把人家做的东西全盘理解透彻了以后再说,否则,一叶障目,不见泰山,一知半解的情况下就大肆嘲讽,说什么“糟蹋JSF”诸如此类的言语,你不觉得惭愧吗?

我承认,我是和AOM有点关系,我是他们的用户,他们曾经给我们公司进行过AOM的培训。
思想不思想的我不想谈,至少我认为,AOM给我带来了开发效率的提升,仅评这一点,至少我很满足。

扯吧扯吧,跟一个满口'丫丫'的人,有什么道理可讲?
hax 2008-04-03
叫hax的好像只有我一个。不过爱民的书好像还没有上市。
dboylx 2008-04-03
您是周爱民在Javascript书里提到过的HAX?
hax 2008-04-03
这里我再说一下@BeforeRender作为例子。一直有人咬定我不懂JSF,我一直没发声音。既然正主回来了,我就说说。

其实我一直强调的是你带给开发者怎样一种开发模式。譬如ROR他给开发者就有很清晰的套路。而@BeforeRender就是一个看不出套路的东西。只是因为JSF有Render阶段,你就把它暴露给一般开发者,这是没有道理的。按照我对JSF的粗浅理解,只有组件开发者才可能会需要像BeforeRender这样的功能。我认为按照JSF的理念,一般开发者是没有必要去接触Render阶段的。特别是你在managedbean上更没有什么理由一定要在render之前干什么事情。如果你引入这样一个@BeforeRender,实际上引诱了一般开发者不恰当的乱用。比如像IoVC例子里那样,用@BeforeRender进行字段初始化,我认为就实在是太拙劣了。
hax 2008-04-03
嗯。我希望AOM能真正做出好东西来。

之前有人质问我,你咋不做个框架出来呢?其实这不是说我要做一个框架就能做出来。真正要做到一个有商业目标的完整的产品,靠个人是不可能的,一定要有资源,而在国内这样的资源更是稀缺。金蝶现在有资源,所以更希望金蝶不要把精力浪费在华而不实的东西上。

还有,我讲的那些思路也没有什么了不起,都是我从其他设计和框架中学来的。譬如在view中分离model和ui controls,就是从XForms中学来的。既然没有什么真正创见,我认为我自己就没有必要去花力气做。相反,我在某些领域,譬如JS、CSS等还算有点独创性,所以我会做这些方面的工作。

AOM的问题我认为有两个,第一是JSF思路的牵制,我们看到AOM也看到了JSF的一些问题,希望能做一些突破,譬如IoVC,然而恰恰是IoVC的设计过于草率(至少就我看到的描述)使得其似乎还不如JSF原本中规中矩的设计合理。第二就是自己整个开发理念和模式尚未似乎有统一认识,常出现自相矛盾的地方。比如Elite的介绍文字。
xyz20003 2008-04-03
在国内搞技术研发什么的,一定要脸皮厚,不要怕被骂,有骂声才有发展,能容忍才有进步。

更何况hax完全是好意,帖子里都是讨论技术的成分,又不是无理取闹。

俗话讲,兼听则明,希望aom一路走好。
apusiczhang 2008-04-03
这几天一直在外面出差,不能及时上网。看到这篇文章受到大家如此的关注,欣慰之余又颇有几份惶恐。
简单谈一下我的个人看法:

技术上:软件技术原本就没有绝对的优秀与粗劣,尤其在谈这种理念、模式之类的东西。IoVC只是我们的一种思考与探索,各位的一些意见我们会积极吸收。但同时需要指出的是:把IoVC等同于几个@Bind的标注,再或者id的指定等等,确实是有些片面。至于“心虚”与否,呵呵,我们向来是很“虚心”的听取各位的意见。虚心,但绝非心虚,呵呵,没偷没抢的,为什么要心虚呢?

情感上:这里也不想去扯什么民族软件的大旗,我们只是在做我们自己的一份事情而已。感谢各位对OperaMasks的厚爱,各位的鼓励会成为我们不断前进的动力,而各位的批评,无论是善意的还是非善意的,我们该听取的一定会听取,该一笑而过也会一笑而过。

行动上:说不如做,且让我们静下心来,把程序写好,把产品做好,这才是我们的本份。

再次感谢大家的关注!
dboylx 2008-04-03
上星期刚参加北京的英雄大会,金碟的技术总监唯一的一场演讲就是这个项目,可以看出金碟高层对些项目的重视。

前两天从CVS上下载了项目源码,JSF组件设计相当的精巧与老练。实现相当漂亮,佩服一个~~赞一个先。

看了很多HAX大师与英雄们的讨论,想听听袁老大对此是什么看法,设计者什么想法。
hax 2008-04-03
黄皮肤黑眼珠又怎么样了?日本人朝鲜人越南人都是黄皮肤黑眼睛。

我最烦扯什么民族大旗了。

我做不做框架跟我能不能批评AOM有什么关系?
asheng88 2008-04-03
令狐不冲 写道
兄弟客气,“根正苗红”实不敢当。金蝶白手起家,靠技术靠拼命。老徐老蔡,三四十岁已头发花白。争得就是一丝基础软件血脉。
中国人做点东西不容易,叫的响了一点,吼的急了一点也是希望有人关注。众人拾柴火焰高,以一家之力做好一个社区显然不实际。
各位低手高手高高手,恳请多些理解,少些嘲讽;多些宽容,少些争斗;多些建议,少些叫板。再怎么说,咱还都是黄皮肤黑眼珠。

说得好,hax貌似高人,放个框架到社区来让大伙瞧瞧?
xxjhappy 2008-04-03
---重复提交,编辑掉---
xxjhappy 2008-04-03
hax 写道

还有,IoVC既然是新的不成熟的东西,那就表急吼吼的自称什么新思想,比MVC更好的MVC……

金蝶本来根红苗正,不是我看不惯他,实在是他自己太浮躁。丫如果真腰板(技术)够硬,十个我也拿他没辙不是么。


我有时看着hax兄的逻辑就真的不知是哭好还是笑好。这个回贴不谈技术,只谈逻辑。一说技术最后又给扯到什么非技术因素上,闷。。。

IoVC既然是新的不成熟的东西,那就表急吼吼的自称什么新思想。 —— 思想和实现是有区别的好不好。就象hax兄的理想框架一样,思想新颖,考虑周全,而且如果做的话,功能将会非常强大。但是你一天不做,思想再高也没用,等到你哪天做出来了,我们再来探讨完善不完善,成熟不成熟的问题。但有一点我是挺肯定的,如果有一天hax兄真的挺身而出,组建一支团队,雄心勃勃地把理想中的框架实现出来之后,他会悄悄的在javaeye上脚踏实地的发个不起眼的小贴,说“小弟不才,做了个小小的程序,可以适度增强大家对MVC框架的理解,请大家赏脸帮忙试用。下载地址 www.334455.com,人格保证,绝无病毒,请放心使用。”

金蝶本来根红苗正,不是我看不惯他,实在是他自己太浮躁,(于是我看不惯他)。—— 一句话里面直接就前后矛盾了。

丫如果真腰板(技术)够硬,十个我也拿他没辙不是么。 —— 你现在拿人家有撤么?什么叫“丫如果。。。”
令狐不冲 2008-04-03
hax 写道
anakin1978 写道
不管它是好猫还是坏猫,IoVC既然是新东西,就必然会有不完善的地方,比如前面讨论中提到的两个UIControl不能使用同一个id来绑定这个问题,也许目前不能绑定吧(俺还没试过,也不知道真伪,现在忙的很),但AOM团队就把它做成能用一个id来绑定又怎么了?这个设计不难吧?下面俺来越俎代庖一下,UIControlI是个接口,现在提供两个实现,一种是常规的,叫UIControlSimple,把它看成原来一个id只能绑一个时的实现,一个是新添加的,叫UIControlComposite,它持有一个view中所有该id对应的UIControlSimple实例,接下来,对UIControlComposite的所有操作,都被适配到真正的UIControlSimple上去了,这样ok吧?当然,这里还有问题,我希望我在其中一个ui上动作不会导致两个ui响应,这里还要做些特殊处理,可以偷偷摸摸的给具有相同id的ui渲染一个特殊标识出来,这样,就可以找到对应的UIControlI实例了。这个思路是否有问题,还请各位点评,俺要偷懒了,玩游戏去。。。



id是唯一标识符好不好。你至少要懂得换个属性成不成。
所以,你就别给AOM添乱了,人多厉害啊,你想到的他们能想不到么?

还有,IoVC既然是新的不成熟的东西,那就表急吼吼的自称什么新思想,比MVC更好的MVC……

金蝶本来根红苗正,不是我看不惯他,实在是他自己太浮躁。丫如果真腰板(技术)够硬,十个我也拿他没辙不是么。

 

兄弟客气,“根正苗红”实不敢当。金蝶白手起家,靠技术靠拼命。老徐老蔡,三四十岁已头发花白。争得就是一丝基础软件血脉。 

 

中国人做点东西不容易,叫的响了一点,吼的急了一点也是希望有人关注。众人拾柴火焰高,以一家之力做好一个社区显然不实际。

 

各位低手高手高高手,恳请多些理解,少些嘲讽;多些宽容,少些争斗;多些建议,少些叫板。再怎么说,咱还都是黄皮肤黑眼珠。

 

xxjhappy 2008-04-03
其实要一个属性绑多个id这种实现细节要做我想应该是不难的,只是目前这个版本没提供罢了。也许正如anakin1978兄所说,AOM2.0是IoVC的第一个实现,必然有不完善的地方。我跟踪过一下IoVC绑定的流程,事实上到最后它的实现是在restore view阶段恢复了组件树之后,根据绑定规则创建一个EL绑到组件对象上,因此在后续生命周期和标准JSF的流程是合二为一的,所以标准JSF能做的,原则上它都能做。只是目前它没有提供一种方便的语法让我们这样做而已。

事实上AOM2.0中有个标签叫@Validate,用来为组件绑定校验方法的,它就可以用
    @Validate(id={"first","second"})
    private void validate(FacesContext context, UIComponent component, Object value) {
    }

的形式把两个组件的校验行为绑到同一个方法上(以上代码来自AOM的示例rcdemo的CalcBean),只是目前@Bind没有提供这样的写法。希望下个版本可以完善吧。
hax 2008-04-03
anakin1978 写道
不管它是好猫还是坏猫,IoVC既然是新东西,就必然会有不完善的地方,比如前面讨论中提到的两个UIControl不能使用同一个id来绑定这个问题,也许目前不能绑定吧(俺还没试过,也不知道真伪,现在忙的很),但AOM团队就把它做成能用一个id来绑定又怎么了?这个设计不难吧?下面俺来越俎代庖一下,UIControlI是个接口,现在提供两个实现,一种是常规的,叫UIControlSimple,把它看成原来一个id只能绑一个时的实现,一个是新添加的,叫UIControlComposite,它持有一个view中所有该id对应的UIControlSimple实例,接下来,对UIControlComposite的所有操作,都被适配到真正的UIControlSimple上去了,这样ok吧?当然,这里还有问题,我希望我在其中一个ui上动作不会导致两个ui响应,这里还要做些特殊处理,可以偷偷摸摸的给具有相同id的ui渲染一个特殊标识出来,这样,就可以找到对应的UIControlI实例了。这个思路是否有问题,还请各位点评,俺要偷懒了,玩游戏去。。。



id是唯一标识符好不好。你至少要懂得换个属性成不成。
所以,你就别给AOM添乱了,人多厉害啊,你想到的他们能想不到么?

还有,IoVC既然是新的不成熟的东西,那就表急吼吼的自称什么新思想,比MVC更好的MVC……

金蝶本来根红苗正,不是我看不惯他,实在是他自己太浮躁。丫如果真腰板(技术)够硬,十个我也拿他没辙不是么。
hax 2008-04-03
anakin1978 写道
是你搞反了吧?是在bean的编辑器里检查,不是在页面的编辑器上检查啊,view里的id才是源嘛,只要bean中@bind了id就去看看view是否已经指定了这个id不成么?当然,这需要扩充java editor的能力,好像现在的editor都不能检查annotation中的字符串是否正确,AOM开发团队既然能做可视化编辑器,他们应该能做到这点的,只是这已经超出我知识范围,我就不坚持了。我退一步说,在运行期进行检查也可以啊,只要在运行期发现bind指定的id不存在,抛个明确的RuntimeException,有详细信息,如果我是用户,我想我是可以接受的。


我没有搞反。如果像你讲的这样,bean中指定了bind,view中一定要有,当然也是一种做法。但你也要考虑这样可能带来的问题,那就是这个bean很难用在不同的view中。我举个例子,假设你有个wizard,有5个步骤,分别对应5个view,你要么为每个view写一个单独的bean(这恐怕很难让人接受),要么就是每个view里都要有所有绑定,即使这些绑定该View用不到——你就要考虑怎么把他们在view上disable掉,不显示,也不参与validate之类的。

总之IoVC这样改变JSF的既有做法,我没有看出有什么好处,反而坏处一堆。你认为
JSF标准的 <command action="abc"> + getAbc()
和IoVC的 <command id="abc"> + @bind(id="abc") getAbc()
到底哪个比哪个更方便呢?
发表评论

提醒: 该博客已发表在公共论坛,博客所有留言会成为论坛回贴,留言请注意遵守论坛发贴规则

您还没有登录,请登录后发表评论

apusiczhang
搜索本博客
博客分类
最近加入圈子
存档
最新评论