`
apusiczhang
  • 浏览: 17421 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

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/

 

分享到:
评论
88 楼 hax 2008-03-28  
大哥,不知道你说的是那种类型的二次开发。一种是在一个比较高层面的平台或框架上开发,这种就没有谁快谁的问题,而只是平台的能力和限制的问题。另一种是裁剪系统以及扩展系统,那就通常不会“改”业务层,而只是做少量配置。当然也有真的要改动业务层的时候,那通常是该系统只满足部分需求,这种其实最让人头痛,除非你只是增加删除几个字段,或对视图稍加修改——而不是去动application logic——从前面yuan同志的只字片语来看,IoVC主要是适用这种本来就挺简单的场景,比较类似从model自动生成或填充UI上的数据——个人认为这个价值太小(不过是省去了一层formbean而已),抵不上引入的隐患。

87 楼 sxsxsx3 2008-03-28  
hax 写道
“坦白说用google快十年,就没发现它的展示有怎么变过,MSN web邮箱也是用了这么久只变过一次。”

不行了,为什么你们举的例子都那么令人无力啊!

“展示层发生根本性结构变化的次数,屈指可数”——请问什么是根本性结构变化?非根本性结构变化又是什么?次数是不是一手数得过来?

前面已经说了,这里谈view/model,只是mvc里的model和view。不要扯到几层service之后的那些model(比如db model?)那里去吧!

“只要业务层一变,或者更具体点,只要业务层到展示层的接口一变,展示层就必然要跟着变。”

业务层变化=>业务层到展示层的接口变化,这有必然的因果关系么?如果真的必然变化,那说明什么问题?如果展示层本身真的没有变化的要求,难道不能维持接口不变吗?facade、adapter、proxy、bridge等等都吃干饭的啊?

“还会有一大批程序员从小就认为展示层必然比业务层易变呢?”

这是因为,展示层确实是比业务层易变。企业应用系统的本质就是如此。你跑来说我做UI库的,我的UI库要适应不同的数据源,所以是展示层稳定,业务层易变。那叫狡辩。因为对于做UI库的来说,UI库就相当于企业应用的业务层了。

任何一个企业应用的目标都是稳定的业务层。做得到做不到那是另外一回事情。

“如果只在web展示的范围内考虑多个展示,那么如何让模型的变动尽可能不影响到展示,则更为重要。因为如果模型变动必然会影响到展示,一个模型变动会导致N个展示跟着变。”

所以我不知道你这个话是站在什么立场在说,如果你是站在Web框架开发者的角度,那么拜托,这个视角是不同的好不好。

“不要在计算加法的函数里写printf,因为要分离展示与逻辑。”

拜托,这是强调分离展示和逻辑么?这本来就是一般的职责分离而已。

“那为什么他不能说如果明天我们要把数字加法改为字符加法,只改算法函数就可以了?”

为什么不可以?当然可以!只要你的需求是需要做这种抽象的话。

“是不会刻意强调“如果业务层变动比展现层变动要快”的场景的,道理很简单,因为此题无解。”

请给出“业务层变动比展现层变动快”的例子。

“JSF的嵌入EL表达式,JSP的<%! %>,libtag, struct的url pattern。”

我说的不是这种东西。我说的是组件与数据源绑定。例如<select source="mylist.xml">这类的。

“IoVC而在模型里绑展示层,绑什么?绑id”
“模型代码事实上不管另一端是什么组件,展示组件也不管另一端是个什么接口签名”

你说的这个跟我直接在网页里内嵌${xxx}有什么区别?
我看下来貌似就是自动反射(或者通过annotation)java类的property,然后populate成一堆html属性而已。请问,这比自定义Taglib优势在哪里?

不要告诉我优势就是:没有限制。

“IoVC只是提供了在某些特殊场景下可以这样做的机会。这正如c语言不会禁止你写段代码低级格式化系统硬盘,但并不代表它推荐你没事就格式化。通过这样做,IoVC弱化了模型与展示之间的单向耦合,令它们可以分别独立演化。 ”

这种说辞很无力。什么叫框架。框架就是要给出规约,要强制一些规则。而IoVC却是堂而皇之的允许java类直接去设定html上的属性,我猜不久就可以看到java类里面出现许多javascript的onxxx的handler。

“通过这样做,IoVC弱化了模型与展示之间的单向耦合”

真没看出来哪里弱化耦合了。我看到的是危险的侵入性,打破分层,可能被用来hack。如果你说IoVC可以起到一点代码生成的作用,倒还好说。

关于耦合还有一点,你要绑定id。我问,html上id变了咋办呢?
你不要回答我说id是不准变的。

“IoVC对这个问题的解决方案是,展示层设计人员只需要在页面上放一个button组件,或者一个link组件,或者一个TreeNode,随便什么东西,并指定id。他需要与模型程序员约定:“我会放一个id叫submit的东西……是啥你别管……来提交表单,用一个id叫birthday的东西来显示生日,你自己看着办。””

你说的无非是分离表现层中的data instance、submission和ui control。想法是好的,但是认为让IoVC根据id来填充数据就能解耦就本末倒置了。这里IoVC是可有可无的(如果不是起反作用的话)。关键是你有好的表现层架构,跟业务层根本无关。XForms就是很好的例证。


怎么感觉有点像在做问答题阿?呵呵,不过从上面帖子来看,前面回帖的那个哥们对那IoVC确实是有用过并研究过,以后有什么问题请教的话还请多指点。不过好像业务层比展现层变化快的例子还有不少的,不然那么多客户为啥需要对自己的应用二次开发呢?我觉得不是因为展现层不好看吧。
86 楼 hax 2008-03-28  
DanielYuan 写道
这篇文章从一开始就没有说清楚,而且所举的例子也不恰当。IoVC并不是要将model绑定到view中,那些annotation只不过是表象。IoVC所做的是将一个活动的、易变的、复杂的交互逻辑用不同的视图表现出来,model和view都是对同一个事物的不同表述,就象在工程制图中用三个二维视图描述一个三维实体一样。Model关心的是业务逻辑,而view关心的是展现逻辑,但他们都是为应用逻辑服务的,因此是对应用逻辑的投影,当应用逻辑发生变化,它的两个投影也将同时发生变化。在传统的Web MVC中model和view之间存在一些辅助线,以帮助反映对逻辑实体的联动变化,IoVC去掉了这些辅助线,使整个架构更加简洁。

严格来说,IoVC并不是一个MVC架构,只是借用了MVC架构中的一些概念。


我们想看例子解说。
85 楼 hax 2008-03-28  
我把本文顶楼又读了一遍:结论——就顶楼而言,IoVC就是一种会自动填充属性的高级JSP。
84 楼 hax 2008-03-28  
“坦白说用google快十年,就没发现它的展示有怎么变过,MSN web邮箱也是用了这么久只变过一次。”

不行了,为什么你们举的例子都那么令人无力啊!

“展示层发生根本性结构变化的次数,屈指可数”——请问什么是根本性结构变化?非根本性结构变化又是什么?次数是不是一手数得过来?

前面已经说了,这里谈view/model,只是mvc里的model和view。不要扯到几层service之后的那些model(比如db model?)那里去吧!

“只要业务层一变,或者更具体点,只要业务层到展示层的接口一变,展示层就必然要跟着变。”

业务层变化=>业务层到展示层的接口变化,这有必然的因果关系么?如果真的必然变化,那说明什么问题?如果展示层本身真的没有变化的要求,难道不能维持接口不变吗?facade、adapter、proxy、bridge等等都吃干饭的啊?

“还会有一大批程序员从小就认为展示层必然比业务层易变呢?”

这是因为,展示层确实是比业务层易变。企业应用系统的本质就是如此。你跑来说我做UI库的,我的UI库要适应不同的数据源,所以是展示层稳定,业务层易变。那叫狡辩。因为对于做UI库的来说,UI库就相当于企业应用的业务层了。

任何一个企业应用的目标都是稳定的业务层。做得到做不到那是另外一回事情。

“如果只在web展示的范围内考虑多个展示,那么如何让模型的变动尽可能不影响到展示,则更为重要。因为如果模型变动必然会影响到展示,一个模型变动会导致N个展示跟着变。”

所以我不知道你这个话是站在什么立场在说,如果你是站在Web框架开发者的角度,那么拜托,这个视角是不同的好不好。

“不要在计算加法的函数里写printf,因为要分离展示与逻辑。”

拜托,这是强调分离展示和逻辑么?这本来就是一般的职责分离而已。

“那为什么他不能说如果明天我们要把数字加法改为字符加法,只改算法函数就可以了?”

为什么不可以?当然可以!只要你的需求是需要做这种抽象的话。

“是不会刻意强调“如果业务层变动比展现层变动要快”的场景的,道理很简单,因为此题无解。”

请给出“业务层变动比展现层变动快”的例子。

“JSF的嵌入EL表达式,JSP的<%! %>,libtag, struct的url pattern。”

我说的不是这种东西。我说的是组件与数据源绑定。例如<select source="mylist.xml">这类的。

“IoVC而在模型里绑展示层,绑什么?绑id”
“模型代码事实上不管另一端是什么组件,展示组件也不管另一端是个什么接口签名”

你说的这个跟我直接在网页里内嵌${xxx}有什么区别?
我看下来貌似就是自动反射(或者通过annotation)java类的property,然后populate成一堆html属性而已。请问,这比自定义Taglib优势在哪里?

不要告诉我优势就是:没有限制。

“IoVC只是提供了在某些特殊场景下可以这样做的机会。这正如c语言不会禁止你写段代码低级格式化系统硬盘,但并不代表它推荐你没事就格式化。通过这样做,IoVC弱化了模型与展示之间的单向耦合,令它们可以分别独立演化。 ”

这种说辞很无力。什么叫框架。框架就是要给出规约,要强制一些规则。而IoVC却是堂而皇之的允许java类直接去设定html上的属性,我猜不久就可以看到java类里面出现许多javascript的onxxx的handler。

“通过这样做,IoVC弱化了模型与展示之间的单向耦合”

真没看出来哪里弱化耦合了。我看到的是危险的侵入性,打破分层,可能被用来hack。如果你说IoVC可以起到一点代码生成的作用,倒还好说。

关于耦合还有一点,你要绑定id。我问,html上id变了咋办呢?
你不要回答我说id是不准变的。

“IoVC对这个问题的解决方案是,展示层设计人员只需要在页面上放一个button组件,或者一个link组件,或者一个TreeNode,随便什么东西,并指定id。他需要与模型程序员约定:“我会放一个id叫submit的东西……是啥你别管……来提交表单,用一个id叫birthday的东西来显示生日,你自己看着办。””

你说的无非是分离表现层中的data instance、submission和ui control。想法是好的,但是认为让IoVC根据id来填充数据就能解耦就本末倒置了。这里IoVC是可有可无的(如果不是起反作用的话)。关键是你有好的表现层架构,跟业务层根本无关。XForms就是很好的例证。
83 楼 xxjhappy 2008-03-28  
hax 写道


这里有一点,尽管经典MVC和web MVC是不同的,但是有一点相同,就是model都是不依赖view/controller的。这也是前面许多同志质疑IoVC的地方。因为他在model上标注了对view的具体细节的映射。那我view变化了,model也要变化了。如果你只是要将一个特定组件与数据源绑定起来,那为什么不是在组件的markup里去绑定数据源,而反过来在数据源里去绑定组件?

model修改而view修改,这是所有模型里面共性的,也是情理之中。model修改意味着你的需求(业务逻辑)变化了,那业务逻辑变化,界面十之八九是要随之改动的。另外一点,后端也是可以分层的,我们这里只谈跟controller发生关系的model。

所以很少有人担心model修改而view修改,而会担心view修改引起model修改,这个连锁反应就大了。这个我们都有体会,只听说美工改了页面,程序员挠头,很少听说过程序员改了java类,美工挠头的。呵呵。


看了这么多回复,觉得这段话真是完全反映了问题所在。对IoVC的质疑声音,大都是集中在它没有遵守MVC在多年前灌输给我们的一个假设:展示层必然比模型层易变。事实上真是如此吗?其实未必,坦白说用google快十年,就没发现它的展示有怎么变过,MSN web邮箱也是用了这么久只变过一次。各大门户网站,虽然内容在天天变,但展示层发生根本性结构变化的次数,屈指可数。至于一些相对较小的电子商务网站,既然运行良好,很少看到有没事变着界面玩的(当然变化是有,但通常都是业务需求发生了改变,这种改变十有八九会触动业务逻辑,是表现层和模型层一起变)。相对来说,业务模型的变动,其实是频繁得多,我相信这点没有人会否认。这些变动有的是必然会影响到表现层结构的,有的则未必,但在传统MVC中,只要业务层一变,或者更具体点,只要业务层到展示层的接口一变,展示层就必然要跟着变。这是现状。我并不是一口咬定业务变动必然比展示层变动多(虽然事实很可能如此),但至少没有任何迹象表明,展示层的变动必然比业务变动多。

其实纵观当前大多数关于分层架构比较稳重的说法,对于view的分层并不是因为它的易变,而是因为它的多样。也就是说你往往需要为同一个业务模型设计多个展示,并同时运作,而不是说你会有一个或多个展示在业务模型稳定的情况下,不停地变动。这个帖子既然已经说明了在探讨web展示,那么就不应该担心除web以外的其他展示(如果一定要担心,正如楼上某位所说,需要把JSF的后台bean看作一种页面bean,只在里面放页面行为逻辑并调用业务逻辑。而其他展示则直接调用业务逻辑,这是在这种场景下必要的分层。这时即使你不用JSF,都应该把界面行为与业务行为明确分离)。而如果只在web展示的范围内考虑多个展示,那么如何让模型的变动尽可能不影响到展示,则更为重要。因为如果模型变动必然会影响到展示,一个模型变动会导致N个展示跟着变。

那为什么在这种情形下,还会有一大批程序员从小就认为展示层必然比业务层易变呢?我觉得有一句话非常能说明问题:“如果你手里只有锤子,你会觉得一切东西看起来都象钉子”。从小我们的C语言的老师就教育我们:“不要在计算加法的函数里写printf,因为要分离展示与逻辑。这样有什么好处?如果明天我们要把文本输出的东西改为在图形界面输出,只改负责输出的函数就可以了”那为什么他不能说如果明天我们要把数字加法改为字符加法,只改算法函数就可以了?原因很简单,负责业务的函数的输入类型和输出类型都发出了改变,负责输入输出的展示层逻辑必然要跟着变。从这个方向来看,分离根本没有任何意义。再深入一点说,传统的分层,事实上是一种服务提供者与服务消费者的分离。服务消费者在服务提供者给定的约束范围内可以有限度地变动(服务提供者根本不知道消费者的存在,消费者要遵守提供者给出的接口协议),但服务提供者的变动则倾向于传递给消费者。

这个问题事实上到了MVC阶段也没有很好的解决方案,以MVC为基础的编程模型,是不会刻意强调“如果业务层变动比展现层变动要快”的场景的,道理很简单,因为此题无解。或者说,既然技术上不能解决,那么就从观念上解决。我们仔细来品味一下引文中的这句话“model修改而view修改,这是所有模型里面共性的,也是情理之中。model修改意味着你的需求(业务逻辑)变化了,那业务逻辑变化,界面十之八九是要随之改动的。” 这让我想起一个故事:某人找算命先生算命,算命先生说:“你命途坎坷,二十岁落魄,三十岁流浪,直到四十岁……”某人大喜:“四十岁如何?”“那时你就习惯了。” 改model必然要改view,已经成为一种习惯,一种“情理之中”,程序员们在习惯中痛并快乐着,已经来不及去管这种状况是否必然,是否合理,甚至会对试图解决问题的人嗤之以鼻了。仅从IoVC着眼于解决这个多年宿疾这点,我觉得IoVC当之无愧可以称得上是一种思想的,虽然它尚处于雏形。但事实上当年谁也不知道,一个病人在床上无聊地发现非洲与美洲的海岸线长得很像,到后来会变成了地壳板块漂移学说。解决问题本身也许不算思想,发现一个多年以来放在人们眼前的问题并尝试去解决,则可称之为思想了。

以我到目前的理解,IoVC事实上并不是什么繁杂的框架,也没有什么很深刻的理论。它是从这两方面去解决上面的问题的:

首先是弱化服务提供者与消费者的耦合。如何弱化?通过id绑定,这正好回答了hax兄提出的问题:“如果你只是要将一个特定组件与数据源绑定起来,那为什么不是在组件的markup里去绑定数据源,而反过来在数据源里去绑定组件?” 在markup里绑模型,绑什么?绑接口。JSF的嵌入EL表达式,JSP的<%! %>,libtag, struct的url pattern。本质来说,都是嵌入在展示层的模型层接口。既然通过接口绑定,就必然涉及到接口签名,数据类型,命名规则,或者各种各样的约定,而这些规则约定天生是与业务逻辑耦合的,这种耦合只能弱化,不可能消除,一旦变化,必然传递到展示层。IoVC而在模型里绑展示层,绑什么?绑id,一个简简单单的字符串key。对于简单值,模型代码事实上不管另一端是什么组件,展示组件也不管另一端是个什么接口签名,例如一个字符串,可以绑在textField上,也可以绑在dateTimeField上;一个组件id,可以帮在简单的对象域上,也可以绑在public String getPersonName()上。程序员只需要告诉网页设计人员:“如果你想用个随便什么东西显示这个人的生日,请把那东西的id设为birthday”,或者反之,网页设计人员告诉程序员:“我这里需要显示个生日,请你在那个什么地方——好像叫做对象私有域还是属性什么的——指定个birthday”。如果是传统做法,程序员只能告诉网页设计人员:“请你在个可以显示字符串的组件上引用myBean.getPerson(id).getBirthday()。”,没有反之。IoVC也允许通过id来绑界面组件的模型类,并进行各种循规蹈矩或者离经叛道(例如指定style什么的)的动作,这里事实上没有什么新东西,如果你循规蹈矩,那么就是标准的JSF编程模型(这里只谈IoVC,不谈AOM其他的功能例如消除视图状态等)。如果你离经叛道,那么可以在bean里控制展示层任何东西,当然没有任何人(包括AOM的开发者)会建议你这样做,IoVC只是提供了在某些特殊场景下可以这样做的机会。这正如c语言不会禁止你写段代码低级格式化系统硬盘,但并不代表它推荐你没事就格式化。通过这样做,IoVC弱化了模型与展示之间的单向耦合,令它们可以分别独立演化。

其次,提供了将系统行为的发起点后移到模型中的选择。此话怎讲?我们知道,目前大部分编程模型,系统行为的最根本的发起点,是在展示层代码中。这个方案背后的原因很简单,简单到大部分编程模型拿它一点办法都没有:因为说到底系统行为的实质发起者是用户,而展示层是与用户交互的接口,一切用户的行为都要通过展示层传递给系统。在这种背景下,在展示层嵌入对模型的调用逻辑是无可避免的,这个发起点可能是一个EL表达式,或者一个特定形式的URL,或者一个taglib标签,或者一段JavaScript,由它去触发一系列的后续行为。这就形成了模型与展示的一个耦合点,再次涉及到接口签名,调用规则等诸多约定。只要这些耦合点存在,展示层就不可能脱离模型独立演化,而编写展示层的人员就必须与模型层人员制定一系列的约定,关注许多与人机交互毫不相干的东西。IoVC对这个问题的解决方案是,展示层设计人员只需要在页面上放一个button组件,或者一个link组件,或者一个TreeNode,随便什么东西,并指定id。他需要与模型程序员约定:“我会放一个id叫submit的东西……是啥你别管……来提交表单,用一个id叫birthday的东西来显示生日,你自己看着办。” 而不是由程序员跟他说:“如果你要提交这个表单,需要导航到这个url,如果你要提交那个表单,就要去那个url,其实很好记,它们前面的context root……就是域名加上/humanresource/那部分都相同,只是后面……还有生日这里需要写条表达式,你有没有带纸笔?”

AOM2.0还没有正式发布,以上只是我到目前为止根据一些资料和自己试用对IoVC的初步理解。但我觉得,即使退一步来讲,也许AOM2.0对IoVC的实现还不算完美,但它的着眼点是为一个已经存在多年,以致很多程序员都视若无睹的问题,试图提出一个自己的解决方案。这种气魄,以及它对国人开源社区的意义,是配得起思想二字的。
82 楼 pig345 2008-03-27  
hax 写道
web框架的思路成了:html只是render出来的结果而已。View是咱自搞的一套(轮子一套一套啊!)。模板标签等等都是我们用来抹杀BS鸿沟的手段,可惜最终都失败了。现在的指望就是jsf或类似之类的方案,他全盘抽象,你甭写html甭写js。你写我的组件,我帮你翻译。至于做出来的效果怎样,你要相信我的renderkit嘛。

一个字,难!
据称在ROR早期给予component很大希望,但在后来几乎被完全抛弃了。
传统web的东西(非ajax)不可能完全和C/S GUI程序一样。
如果认识到这一点,或许接受html,js,css配合模板式view,是一种最好的选择。

(不过最近的js/ajax框架,如ext之类的,到像是把web变成了基于浏览器平台的c/s编程。这个还在学习中,不多说了)
81 楼 spiritfrog 2008-03-27  
感觉这种tag比较费解。。。。通过注解都不知道页面对应bean的什么属性去了。
真的与其学这个,不如更加大胆一点,html更纯净一点
80 楼 Echolee 2008-03-27  
就是IoC嘛 有分别吗? 只是在视图层用而已~
79 楼 DanielYuan 2008-03-27  
这篇文章从一开始就没有说清楚,而且所举的例子也不恰当。IoVC并不是要将model绑定到view中,那些annotation只不过是表象。IoVC所做的是将一个活动的、易变的、复杂的交互逻辑用不同的视图表现出来,model和view都是对同一个事物的不同表述,就象在工程制图中用三个二维视图描述一个三维实体一样。Model关心的是业务逻辑,而view关心的是展现逻辑,但他们都是为应用逻辑服务的,因此是对应用逻辑的投影,当应用逻辑发生变化,它的两个投影也将同时发生变化。在传统的Web MVC中model和view之间存在一些辅助线,以帮助反映对逻辑实体的联动变化,IoVC去掉了这些辅助线,使整个架构更加简洁。

严格来说,IoVC并不是一个MVC架构,只是借用了MVC架构中的一些概念。
78 楼 hax 2008-03-27  
pig345 写道
hax 写道

因为现在web实践的主要矛盾是UI能力不足,人们就想着法儿去只好让controller去干涉一把。
...
UI归根到底是任人摆弄的文本流——而不是像MVC鼻祖smalltalk里面那样V也是真对象。因为搞了半天不过是文本流,所以很难维护独立的UI logic


抛去ajax,就传统web来说,似乎html只是view的生成品。
真正的view是模板、标签和各种其他形式的helper。

模板里面不是不能有脚本,而是不能有业务逻辑的脚本,却一定要有界面展现相关的脚本。
这个可能是一般程序员难以意识到的,即使是使用ROR也还有这个问题,甚至更盛,因为ROR的脚本更灵活。


你说的完全正确。web框架的思路成了:html只是render出来的结果而已。View是咱自搞的一套(轮子一套一套啊!)。模板标签等等都是我们用来抹杀BS鸿沟的手段,可惜最终都失败了。现在的指望就是jsf或类似之类的方案,他全盘抽象,你甭写html甭写js。你写我的组件,我帮你翻译。至于做出来的效果怎样,你要相信我的renderkit嘛。
77 楼 hax 2008-03-27  
sxsxsx3 写道
hax 写道

事实上,我认为“View的能力越强,MVC架构的质量就越高”。


如果View的能力越来越强,是不是说model是一个稳定的model而大部分的能力交由view来处理,这样会不会造成view端的不堪重负呢?如果万一model需要修改,那么view也不可避免的需要改动,这个时候会不会让质量下降?


其实我是针对他说的来对应的说的。这个话本身不严谨。

MVC不是那个部分强不强。因为MVC本身是个架构模式,每个部分并不对应到具体的实现。按说是不存在强不强一说的。我的所谓强不强的意思,其实是指在一个实现MVC或者MVC变种的具体框架里,它的MVC的职责划分是怎样的。

现在至少有两种MVC,一种是经典MVC,一种是Java的Model2。这两者是有差异的,他们对于MVC职责的划分是不同。甚而我觉得其实现在的Web MVC与经典MVC有很大的差异。比如经典MVC是基于观察者模式的,View会注册Model的事件来自动管理自己的刷新。但是传统Web MVC是没法从model推送事件到view上的。所以这个职责就被搞到controller里去了。

按我的看法,这是无奈之举。否则就不会有现在大家都要搞event-driven的web framework了。

所以Web MVC的问题在于View太弱(即职责被弱化了)。这是削足适履(适应HTML/HTTP)的过程。
也就是说,现在不是view不堪重负,而是根本不堪弱负。

这里有一点,尽管经典MVC和web MVC是不同的,但是有一点相同,就是model都是不依赖view/controller的。这也是前面许多同志质疑IoVC的地方。因为他在model上标注了对view的具体细节的映射。那我view变化了,model也要变化了。如果你只是要将一个特定组件与数据源绑定起来,那为什么不是在组件的markup里去绑定数据源,而反过来在数据源里去绑定组件?

model修改而view修改,这是所有模型里面共性的,也是情理之中。model修改意味着你的需求(业务逻辑)变化了,那业务逻辑变化,界面十之八九是要随之改动的。另外一点,后端也是可以分层的,我们这里只谈跟controller发生关系的model。

所以很少有人担心model修改而view修改,而会担心view修改引起model修改,这个连锁反应就大了。这个我们都有体会,只听说美工改了页面,程序员挠头,很少听说过程序员改了java类,美工挠头的。呵呵。
76 楼 hax 2008-03-27  
贡献一个我年轻时代关于MVC的学习过程,供大家参考批判。

发信人: HAX(海曦), 信区: WebDevelop
标  题: Re: MVC在WebE的对应
发信站: 饮水思源 (2002年07月11日19:19:49 星期四), 站内信件

今天继续看了一下,又有一些新的发现。

【 在 HAX (海曦) 的大作中提到: 】
: 今天看了很久以前down下来的一篇文章:
: Objects and the Web
: Alan Knight, Naci Dai (这个名字好像中文名字啊!)
: 其中提到Web分层构架是4层:
: Input 对应于 MVC 的 input controller
: Application logic 对应于 application controller
: Business logic 对应于 model
: Presentation 对应于 view

传统MVC起源于smalltalk这种语言,用于软件开发。但是我们对smalltalk
不了解,很多对方也对MVC想当然,而且有绝对化(神化)MVC的倾向,
但是今天重新看了一下Objects and the Web文章里的图,据说MVC中的
Controller原来只是控制Keyboard、Mouse的,也就是说只是Input Controller,
而且Web上的Input Controller的对象显然不是Keyboard之类而是HTTP的Request
(所以好像看到有熟悉smalltalk的同志抱怨此MVC与stucts实现的MVC不同)……
而且更重要的是原始的MVC中并没有显然的区分Application logic 和
Business logic!仔细想想也是,Smalltalk就是学院式编程,恐怕没有
中间件的概念。

请问诸位同志在学习编程的时候有意识的区分Application logic和
business logic吗?我猜想达不到大量复用和构建复杂应用的需求时,
不会有自觉的Application logic和Business logic的划分吧!

: 俺觉得以前好象对这个对应没有搞得很清楚。主要的问题是
: 对于Application logic跟Business logic有些混淆。因为
: 还有content-logic-style的分法。事实上现在明白了,复杂的
: style还包括presentation logic,而content-logic的分法是
: 与model-controller的分法有差异的。因为对于传统web来说
: 它只有人可以理解的content没有设计model!当然这个判断不
: 是绝对的。因为content(data)既然成为独立的层,好歹会有
: 一些model,但这个model通常不是像MVC中那样是OO的,一般
: 可能仅仅是结构化和半结构化数据,或者是像ER model。显然
: 如果是这种情况,business logic就不能被封装到对象自身,
: 于是就容易与controller(application logic)混淆起来!

这里有点没有说清楚,content-logic和model-controller是有不同,
但是有类似的问题。前者的问题是application logic和business logic
混入logic层(我判断原因是content缺乏oo的表达),后者的问题是
application logic和business logic混入model层(或者毋宁说是还没
有application和business的分层需要)。

: 可是有个疑问,web的content不选择oo model,就一定是错的吗?
: MVC的分层一定适合于WebE吗?我虽然还没有答案,但我倾向于
: Web上需要应用的是一种非传统OO(如RDF)的model。

最后的意思是oo好像也具有封闭性……但是这个想法还很不清晰。


欢迎大家讨论。
--
做系统缺少资产,做应用缺少沟通,做信息缺少分类,
做工程缺少规范,做管理缺少制度,做团队缺少组织……
※ 来源:·饮水思源 bbs.sjtu.edu.cn·[FROM: 202.120.15.34]
75 楼 hax 2008-03-27  
cloudxman 写道
讨论很热闹,我也谈自己的一些观点:

1. 每种技术都有其适用的场景,如果针对这种场景它能很好解决,很方便解决,那就有价值。
2. IoVC的新意不在于Controller去控制UI,而在于在web这种传统单向请求的交互逻辑下,让Controller可以去控制UI, 这在很多时候是符合思维逻辑的连贯性的,也是方便的,但是这种思想有其局限性。
3. JSF 无意去取代很多经典的MVC架构,它的目标是去提升Web的开发效率,大家都知道,在效率和优雅之间往往是存在矛盾的。我们日常生活中大部分的应用其实是更关注效率的,我想这是JSF被纳入一种官方标准,并花力气去推的主要原因吧。

4. AOM 可能在做一件事情,就是在JSF的目标下,想让日常某些Web应用开发更加快捷、更加省力一些。所以从这个角度,大家应该更多从提升Web开发效率角度,多给AOM提建议,提良策,看看还有哪些改进方向,还有哪些可以吸纳进来的。

5. 百家争鸣往往会催生很多有趣的东西,让这一起来得更猛烈些吧。


1. 大而化之的道理就不用说了,每种技术都有适用场景,那不是说每种框架都有道理么。那我们费什么口水呢。

2. Web上的MVC的一大弊病就是与经典MVC相比,controller变得太胖了,操心它不该操心的问题,比如它太操心UI。controller符合思维连贯性,这是在遇到带有状态的流程的时候是这样的。我倒是认为这没有什么局限不局限的问题,思想没有局限,架构才是有局限的。所以关键是你怎么实现它。

3. 你说jsf无意取代mvc,这个有点搞笑,又有点无力。

4. 你说效率和优雅的矛盾不知道是指什么效率。如果是开发效率,那怎么会与优雅矛盾呢?我还没见过不优雅的架构能提高开发效率的——除非以可伸缩性和可维护性为代价——也就是一次性的“和谐”项目。你要说最省力,那就是无为——我不做,我找外包做,嘿。

5. 要更猛烈,那你得先提供更多靶子才行,呵呵。
74 楼 pig345 2008-03-27  
不过web中确实view无法监听model。这个可能是与传统CS结构下MVC的最大区别
73 楼 pig345 2008-03-27  
hax 写道

因为现在web实践的主要矛盾是UI能力不足,人们就想着法儿去只好让controller去干涉一把。
...
UI归根到底是任人摆弄的文本流——而不是像MVC鼻祖smalltalk里面那样V也是真对象。因为搞了半天不过是文本流,所以很难维护独立的UI logic


抛去ajax,就传统web来说,似乎html只是view的生成品。
真正的view是模板、标签和各种其他形式的helper。

模板里面不是不能有脚本,而是不能有业务逻辑的脚本,却一定要有界面展现相关的脚本。
这个可能是一般程序员难以意识到的,即使是使用ROR也还有这个问题,甚至更盛,因为ROR的脚本更灵活。
72 楼 sxsxsx3 2008-03-27  
hax 写道

事实上,我认为“View的能力越强,MVC架构的质量就越高”。


如果View的能力越来越强,是不是说model是一个稳定的model而大部分的能力交由view来处理,这样会不会造成view端的不堪重负呢?如果万一model需要修改,那么view也不可避免的需要改动,这个时候会不会让质量下降?
71 楼 hax 2008-03-27  
apusiczhang 写道

何谓MVC?
笔者以为:所谓MVC,就是要降低Model和View之间的耦合度,同时通过Controller将Model和View之间需要耦合的部分加以控制,因此,Controller的能力越强,MVC架构的质量就越高,IoVC实际上就是要最大程度地增强Controller的能力,使Model和View之间的耦合度降到最低。

和传统MVC比较,IoVC中的model和view之间的耦合度更低,仅仅通过某种映射关系将model和view之间建立关联,
没有什么form bean,action之类的东西,因此model和view可以独立维护(再次重申,我前几篇回复中那个style的例子,确实没有举好,相反,这个例子反而会给大家带来许多误解,认为IoVC就是把view塞进model),而且model和view之间可以是多对多的映射,更可以实现粗粒度的应用组件。

当然,IoVC并不仅仅只是通过几个annotation在Model和View之间建立关联那么简单,它还包含许多其它的东西,如:在IoVC中,还有一种模型事件,View的动作可以触发模型事件,而Model可以监听自己感兴趣的事件;这样做的目的,其实也是为了降低View和Model的耦合度而已。


偶其实对MVC不怎么感冒。传统MVC在web实践中走样了。

我对你的这个论点“Controller的能力越强,MVC架构的质量就越高”不敢苟同。

事实上,我认为“View的能力越强,MVC架构的质量就越高”。

因为现在web实践的主要矛盾是UI能力不足,人们就想着法儿去只好让controller去干涉一把。

MVC的精髓除了解耦之外,更有一点是各个部件可以独立演进。但是现在的情形是V被钉死了。因为它最终就是要拼HTML(或者其他字符串),UI归根到底是任人摆弄的文本流——而不是像MVC鼻祖smalltalk里面那样V也是真对象。因为搞了半天不过是文本流,所以很难维护独立的UI logic。

名字映射当然比直接拼html是降低了耦合。但是我的问题是,名字映射干嘛是在java里的?!为什么由java来定义映射?这其实很奇怪。因为model是稳定的,view是不稳定的。由稳定的一方去映射不稳定的,结果就是不稳定被传导回去了。这种反转有什么价值?假设说,过去你在UI中直接访问java类是一个问题,现在你在java类中去直接干涉UI为什么就不是问题了呢?

其实form bean、action本身没什么不对,它至少是一种对UI的规约——它把千变万化的UI圈在一个可控的接口内,controller只要和这个部分打交道就可以了。这个思路我认为绝对没错,差的是现在的实现方式不够好。让model去随便bind住UI上的某个html元素从而干涉UI,不知道这比form bean好在哪里呢?

“model和view之间可以是多对多的映射,更可以实现粗粒度的应用组件”,“还有一种模型事件,View的动作可以触发模型事件,而Model可以监听自己感兴趣的事件”。愿详闻之。
70 楼 pig345 2008-03-27  
apusiczhang 写道
如:在IoVC中,还有一种模型事件,View的动作可以触发模型事件,而Model可以监听自己感兴趣的事件;这样做的目的,其实也是为了降低View和Model的耦合度而已。


经典CS结构的MVC中,是view监听model的变化,就是说view知道并要了解model的一切,而model不需要操心任何特定的view(业务逻辑就够烦的了,还要管view的一堆烂事???),甚至他都不关心有几个view在关注它...

本质上是从view到model的单向依赖。

如果IoVC在此基础上又添加了一个model对view的依赖,这就把单向耦合变成了双向耦合!那个更差相信都能看得出来(搞不好还可能出现事件无限递归...)

所以你前面一说,我就知道是明显的反MVC的。

不过反就反了吧,如果没遇到事就没问题(真遇到问题够喝几壶的),现在只是让熟悉MVC的大家不舒服而已。
69 楼 cloudxman 2008-03-27  
讨论很热闹,我也谈自己的一些观点:

1. 每种技术都有其适用的场景,如果针对这种场景它能很好解决,很方便解决,那就有价值。
2. IoVC的新意不在于Controller去控制UI,而在于在web这种传统单向请求的交互逻辑下,让Controller可以去控制UI, 这在很多时候是符合思维逻辑的连贯性的,也是方便的,但是这种思想有其局限性。
3. JSF 无意去取代很多经典的MVC架构,它的目标是去提升Web的开发效率,大家都知道,在效率和优雅之间往往是存在矛盾的。我们日常生活中大部分的应用其实是更关注效率的,我想这是JSF被纳入一种官方标准,并花力气去推的主要原因吧。

4. AOM 可能在做一件事情,就是在JSF的目标下,想让日常某些Web应用开发更加快捷、更加省力一些。所以从这个角度,大家应该更多从提升Web开发效率角度,多给AOM提建议,提良策,看看还有哪些改进方向,还有哪些可以吸纳进来的。

5. 百家争鸣往往会催生很多有趣的东西,让这一起来得更猛烈些吧。

相关推荐

    OperaMasks快速进阶

    OperaMasks是一个开箱即用的Web开发解决方案,它的关键特性包括IoVC的编程思想,使得页面设计与控制逻辑分离。此外,它还内置了Ajax支持和丰富的UI组件库,适合开发高交互性Web应用和轻量级、高并发的Web站点。...

    ### 2024年第一季度青岛房地产市场季度简报总结、市场综述

    2024年第一季度,青岛房地产市场经历了显著变化,总体呈现供需双降的趋势。一季度全市商品房新增10,721套,面积约152.04万平方米,同比下降29%;销量为14,936套,面积约200.85万平方米,同比下降38%,成交均价为14,204元/平方米,同比下降2%。土地市场方面,供应总量为39万平方米,同比减少7%,但成交面积为27万平方米,同比增长31%,楼面地价为6,625元/平方米,同比增长253%,土地出让金为17.61亿元,同比增长354%。二手房市场新增挂牌2.9万套,成交13,405套,132.21万平方米,累计挂牌51.70万套,挂牌均价17,800元/平方米。此外,青岛市出台多项政策支持房地产市场平稳健康发展,包括降低房贷利率、优化开发用地土地规划政策、支持房企融资等。这些政策旨在促进市场供需平衡,防止市场大起大落。

    Linux常用命令大全.markdown

    linux常用命令大全

    MATLAB代码,用于模拟具有无限半空间体积导体的电机单元电势(MUP),星号.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    空调销售网站策划案例.doc

    空调销售网站策划案例.doc

    全球6G技术大会2024年以用户为中心的6G接入网技术研究白皮书31页.pdf

    全球6G技术大会2024年以用户为中心的6G接入网技术研究白皮书31页.pdf

    简约专业风格毕业答辩模板47个

    简约专业风格毕业答辩模板是一系列专为追求简洁与高效表达的大学生设计的答辩文档模板,共47个。这些模板融合了经典的设计元素与现代审美,强调信息的清晰传递与视觉的整洁,旨在帮助学生在答辩中以最专业的面貌展示自己的研究成果。 每个模板都具备结构合理的布局,适用于各个学科和研究领域,从人文社科到自然科学,均能满足不同需求。简约风格的设计使得学生能够专注于内容本身,避免冗余信息的干扰,提升答辩的专业性和可信度。此外,模板中合理运用的色彩、字体和图表设计,不仅增强了视觉吸引力,也使信息更易于理解。 通过使用这些简约专业风格的毕业答辩模板,毕业生能够自信地呈现自己的学术成果,提升答辩的整体效果,为成功的学术交流打下坚实基础。这些模板是展示个人研究与风格的理想选择。

    【数据集和模型】ChatGPT文本二分类

    由 Epsilon Luoo 在 HC3-Chinese 的基础上进行了一些细微的修改和清洗

    数字人动作捕捉:MATLAB-Kinect骨骼数据实时插值算法.pdf

    文档支持目录章节跳转同时还支持阅读器左侧大纲显示和章节快速定位,文档内容完整、条理清晰。文档内所有文字、图表、函数、目录等元素均显示正常,无任何异常情况,敬请您放心查阅与使用。文档仅供学习参考,请勿用作商业用途。 你是否渴望高效解决复杂的数学计算、数据分析难题?MATLAB 就是你的得力助手!作为一款强大的技术计算软件,MATLAB 集数值分析、矩阵运算、信号处理等多功能于一身,广泛应用于工程、科学研究等众多领域。 其简洁直观的编程环境,让代码编写如同行云流水。丰富的函数库和工具箱,为你节省大量时间和精力。无论是新手入门,还是资深专家,都能借助 MATLAB 挖掘数据背后的价值,创新科技成果。别再犹豫,拥抱 MATLAB,开启你的科技探索之旅!

    HI3519DV500 配置无线网依赖库以及编译脚本

    HI3519DV500 配置无线网依赖库以及编译脚本

    定制小米8-lineage22.1安卓15-fast功能项目线刷双版root 解锁bl后fast线刷

    资源说明; 1-----刷写前提是手机必须解锁bl先。而且会在fast模式刷写固件 2-----刷写方法与官方刷写步骤一样 3-----此固件为定制初始固件。可以在fast模式刷写 4-----属于适配固件。也许有个别bug。不接受请勿下载 5-----需要一定的刷机常识与动手能力的友友刷写。 6-----资源有可复制性。下载后不支持退。请知悉 7-----定制其他需求可以在csdn私信博主 博文参阅:https://csdn9.blog.csdn.net/article/details/143058308

    【机械臂路径规划】基于matlab快速探索随机树RRT和概率路网PRM串联机械臂路径规划【含Matlab源码 13167期】.zip

    Matlab领域上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    世邦魏理仕:2021年西安房地产市场回顾与2022年展望.pdf

    世邦魏理仕:2021年西安房地产市场回顾与2022年展望

    Android Studio 2022.1.1和java编程语言yinyuebofangqi.zip

    Android Studio 2022.1.1和java编程语言yinyuebofangqi

    C知道对话分享图片下载

    C知道对话分享图片

    png-jpg-gif-webp-tiff等图片压缩工具基于nodejs的实现

    png-jpg-gif-webp-tiff等图片压缩工具基于nodejs的实现,绿色本地免安装,解压后运行exe文件,将图片文件或者包含图片的文件夹拖拽到软件界面即可压缩

    派对屋A1效果器电脑调音软件

    我们要了解什么是DSP(Digital Signal Processing)。DSP即数字信号处理,是一种利用数字计算方法对信号进行分析、变换和操作的技术。在汽车音响领域,DSP被广泛应用于改善音质,通过调整频率响应、延时、相位和增益等参数,使声音更加均衡、立体。 惠威是一款数字信号处理器,适用于那些希望升级原车音响系统但预算有限的用户。它通常拥有多个输入和输出接口,可以连接到汽车的音频源和扬声器,通过软件进行调音,使得声音能够适应不同的驾驶环境和听音偏好。 ,集成了先进的噪声抑制技术和强大的功率放大器,旨在为发烧友级别的车载音响系统提供卓越的性能。用户可以通过软件对整个系统的每一个细节进行优化,包括主动分频、时间校正等,以达到Hi-Fi级别的音乐享受。

    通信工程分包合同.docx

    通信工程分包合同.docx

    demo1(1).py

    demo1(1).py

Global site tag (gtag.js) - Google Analytics