`
apusiczhang
  • 浏览: 16938 次
  • 性别: 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/

 

分享到:
评论
108 楼 jameswxx 2008-03-31  
现在的花花概念真多,JSF就是这样用的,<w:textField value="#{myBean.value}"/>,这样只是取数据方便点,实质上myBean仍然在request或page或session里,只不过框架为你做了这些事情,本质上没区别。
107 楼 pig345 2008-03-31  
treenode 写道
tmj 写道
.net 的webform 不就是这么操作嘛

... 表现层技术能够脱离对服务器端编程语言的依赖,独立实现自身的发展变化,我认为是一个很好的现象,也应当是未来的趋势,对于这种试图将表现层纳入服务器语言强力统治版图的实现思路,我认为它是在开历史的倒车。当然这可能也有我自己的一些偏见在里面,算是一家之言吧。


类似ext这样的ajax框架其实正是 基于browser/webserver平台的 C/S,传统的C/S结构似乎在回归。只不过原来基于操作系统的client变成了基于浏览器的,通信协议也由私有二进制变成了基于http的明文协议。

技术的发展似乎在螺旋上升。
106 楼 xxjhappy 2008-03-31  
既然hax兄喜欢逐句评论的形式,那我也入乡随俗吧。毕竟理解万岁。另外与技术无关的比喻,既然hax兄不满意,也就少说为妙了。

1.“偶是没用过AOM,因为我对JSF根本就不感冒。而且我没有必要也没有义务先要用过AOM再去批评它……”这个当然是没有义务的,至于必要嘛,很难说。那要看hax兄的职业是一个科学家(技术人员)还是一个批评家。如果是批评家,自然可以想批评什么就批评什么。如果是技术人员,打着科学的旗帜来批判,那最好还是先做点调查哦。。。连JSF都不熟悉,只是凭着对自己现有知识的一腔热血,对批评的对象的一大堆的“我猜”,但又摆着统揽全局的姿态来批评,那就的确就点那个“井底之蛙”(按hax兄的建议,这次就不藏头露尾,枉作小人了)的气概了喔。。。

2.关于id为什么会变hax兄懒得回答,我是意料之内,所以我也没有去真的走去问前端人员。不然就算辛辛苦苦问了,人家说不会变,hax兄还是说我懒得理你和你的那个前端,岂不是白搭。。。

对于“框架的作用就是找到一个平衡点,并确保或至少引导开发者始终保持在这个平衡点附近。”这一句我是不敢苟同的,综合以上几个贴子,我觉得hax兄对“程序员”这个词的感觉是一堆前后逻辑毫不连贯,总是在合适的时候做出你想象中行为,所以需要你去引导的群体,而不是一个一个有统一思想的个体。例如说,你笔下的程序员可以今天思路清晰地使用facade、adapter、proxy、bridge等设计模式去保证model接口稳定,可以如有神助地预见到需求的变化而在合适的地方引入抽象。但明天又会突然之间分不清UI行为层与业务model层,在IoVC的“误导”下胡乱涂鸦。如果真得有这样一群程序员,那么就真的可能市面上会出现一种仅仅为了限制而限制的框架。但我所认识的程序员(结合他们手上的项目),没有一个是这样的,他们要么就是明确的架构主义者,善用抽象,熟悉模式,并不需要框架来“引导”,反而如果框架的所谓“引导”(事实上我认为是为了提供方便所制定的规则)与他们的原有知识不吻合,他们可能会反感(hax兄自己是个很好的例子喔,你的信仰是“程序员需要限制”,于是对任何“没有提供必要限制”的东西就会极端反感,虽然我引导了很久,还不是照样不以为然。。。),这时除非框架本身能提供足够的好处,否则他们不但不会接受你的“好意引导”,反而会对你嗤之以鼻。要么就是明确的反架构主义者,他们可能只做轻量级的项目,对分层,模式什么的不以为然,只求尽快把项目做完交货,功能完备,万事大吉(这个群体可能不入hax兄法眼,但是客观存在的,特别在应用软件行业中),对于这个群体你在框架里故意给他加限制那叫自取其辱,要么想尽办法把限制绕过去,要么就直接弃用了,他们不会喜欢一个没有带来任何方便,仅仅是为了所谓的“风格”而加入的限制。还有一些可能还没有如此明确的立场,可能选择任何框架,接受其编程模型,那就至少不会前后矛盾,故意跟他选用的框架过不去,那么框架的编程模型,本身就是一个软限制(如果他在项目组里,那么项目本身现有的风格就是他的限制,会有相关行政措施来保证),而不需要在框架里画蛇添足地情愿牺牲易用性或者性能或者任何其他东西(例如直接牺牲了前面的两类用户群)去专门引入硬性限制。目前最被人们所喜爱的限制,是那些可以帮他们找出“bug”的限制,例如强类型检查,例如java里不允许在if条件中使用赋值表达式,为什么?因为这些限制,给他们带来了方便。但象hax兄例子里那种,放弃了编译检查,又滋长同步冲突,又没有提供任何方便,越帮越忙,仅仅是为了提供规约,号召所有程序员都按着hax兄的思路走的框架,没做出来的时候,看着是觉得挺好。但做出来了有多少人会去用,那就要打个问号了。

“既然认为美工不应该用el,那为什么美工应该用taglib或任何除了html之外的markup?” —— markup是相对稳定的标准东西,超然于业务需求之外。el是各种各样的项目里各种各样的程序员(例如,可能是以上三种的任何一种)写的方法签名,受业务需求影响。不知道这个理由是否充分?

“这里有谁写好java类之后从来不改类名和方法名的?难道就java开发人员掌有“命名”事物的权力,而美工和前端开发者就没有?” 变了类名和方法名,那就要改view中的el。变了id,就要改程序中的绑定,至少字面上比较起来就没有差别呀。但前面说过,类名和方法名改动的驱动力是业务逻辑变动,是程序员自身无法控制的。(除非你用了一大堆虽然不是吃干饭但是要吃很多饭的抽象层去保护它,而且还不一定就能保证绝对不变),我上个贴子问的就是,请问前端人员改id的驱动力是什么?只是为了展示他们的权力?

“但是遇到稍微复杂一点的ui logic怎么办?好了,AOM出hack了,第一招叫做attribute侵入,第二招更狠,直接生成一些javascript嵌入进去。我其实还没有提别的问题,比如我一个view上要用一个model的两个不同的instance怎么办?我猜他就是换一个attribute来侵入,或者还有其他狠招。” —— 不如你说说到底是什么逻辑,我们大家给你想想办法啊。你又不熟JSF,又不熟AOM编程模型,只能猜到这两招是很正常的呀。。。“我一个view上要用一个model的两个不同的instance怎么办”这个东西你平时用el怎么办,我用IoVC就怎么办呀。一般就是在原来的el前多加一层可以分别出两个实例的引用,用IoVC就是把@Bind的getter(两个组件绑不同getter)里引用不同实例。或者,最简单的是,可以用IoVC在ManagedBean里往组件里填el。

BTW那段完全没有看懂,先不妄自推测了。我找你要统计数据是因为你说“展示逻辑变动必然比业务逻辑快”,是要直证(也就是说,要么说出明确的推理,要么举出压倒性的统计数据),我说的是这句话的反面,也就是“不必然”,只需要反证,举了个google足矣,还搭了个MSN,顺带提及了其他电子商务网站。你别管它软不软,反正就说明了“不必然”。“你的约定要是基于过分简化不切实际的假设,那约定得再简单再漂亮也就一个词:意淫。”这句话我绝对同意,特别是“要是”两个字,例如那些不是开玩笑的全部默认绑定云云。。。

“在AOM眼里,view就是一个架子,根本没有logic的”——如果要套上你的有血有肉view的分层,在JSF编程模型里,这个view是由makeup写成的页面与ManagedBean(AOM中改叫LiteBean,因为提供了一些非标准的特性)组成的。makeup只管展示(标准JSF中还管绑定),也就是根本没有logic那部分。ManagedBean管数据和行为(IoVC中还管绑定)。

“虽然他像模像样的说,我们没叫你把style写到bean里——废话,JSP也没叫你把jdbc写到JSP里。”——问题是,现实中的确有人在JSP里写jdbc呀,难道目前有任何一个框架一发现有人在JSP里写jdbc就抛异常?按照你的“框架就是要规约”的理论,个人建议你,可以上书JCP建议JavaEE7不允许在JSP里写jdbc,没准就通过了。这可比跟AOM说事有意义多了!

“我们假设IoVC是把与纯粹的ui控件(空架子)无关的部分解耦出来了,放到了model里。问题来了,你的model到底是什么model?”——如果你严格分层的话,再把业务逻辑和界面行为逻辑分一层,那么ManagedBean部分就是界面逻辑层。当然JSF和AOM都不会用技术手段硬性规定你不准在ManagedBean里写业务逻辑(但不推荐),所以如果想牺牲架构清晰度去换方便(例如自己随便写个小程序玩玩时),也可以把业务逻辑写在ManagedBean里。

关于你随手写的例子,我想问的是,如果用了你这个框架,用户付出了什么,得到了什么?仅仅是“喔,原来el是应该属于view的”?还有我想问下细节,假如你真的推出这个框架,做不做代码提示?如果我一个view写了超过一屏,我每次加el的时候,要鼠标滚轮滚滚滚滚到开头,加条定义,再滚滚滚滚到原来的地方,加条引用吗?还是我跟项目经理说,要写这个页面必须配备两个人分开写开头和中间,你要我一个人写请给双倍的时间或者双倍的工钱?如果你是分开多个独立文件,那我在阅读代码时,看到一个bind="name_of_manager_in_sales_department",又或者bind="b_id3342" (当然,我估计你的框架是会通过某种人工智能禁止这种写法的),是需要用目录搜索工具搜索才能看到实际的el吗?我相信任何一个程序员,做完这种事之后,发现这个引用只被使用了一次,第一个反应是:“你是在耍我吗?”。框架这种东西,想起来是很舒畅,要实现一个出来还要让人能用可不简单呀。

“谢谢你告诉我@Bind可以绑方法,我终于可以写jdbc啦!”——请hax兄写信JCP的JSP项目组时,顺便给JSF的项目组抄送一份。如果标准JSF禁止了,AOM再把这个限制打开,我相信至少又比其他标准JSF产品多了点竞争力。

“甚至,如果是我写ui,而且ui需要的bean都简单得跟IoVC的例子那样,我根本不会把bind单独写到model部分里,而会直接在markup上用el。”——如果个个前端人员都象hax兄一样强劲,我猜这种技术力量乘上这个群体的人数(或者再加上其中的MM人数对其他群体的影响力),足够发明一种简单易用的框架直接把业务逻辑做在前端还能保证各个客户端与数据库信息同步,并解决业务逻辑同步更新问题了。

“两个ui control绑定相同的bean,难道你要他们有相同的id?”——这点的确有道理,我回头跟AOM团队的人交流一下他们有什么解决方案再说。但最简单的,你还是可以直接在页面写el来绑。已经说过,AOM的好处是,如果你的需求超出了它目前实现的能力,它没有给你添加任何额外的麻烦。最多在特殊的那一点上打回原形,在任何其他在它能力范围内的东西还是可以继续享受它的功能。

“强类型检查很了不起吗?虚幻假象!”——也不是很了不起,这东西既不能令程序优雅多少,又没有引导人们奔向美好的架构。对于批判家们是一文不值的。但对于干dirty work的应用软件程序员,还算是聊胜于无的。

“是可以通过工具检查出bind的有效性的。如果bind属性和bind元素的id匹配不上,就说明有错误。”——你意思是,你的model里的条目,如果没有现实的bind跟它匹配,你就会抛异常?这功能有点古怪喔,如果你的model要重用,还要把新view里没有用到的bind id删掉?还是要把新view和原view共有的bind条目抽取出来做一个新文件,各自特有的分离为两个新文件?那如果用户分离了之后,突然又想不要新的那个view呢?我很是怀疑到时候你会做这样的工具,还是偷懒直接把这条判断去掉了。。。

“我确实是这样推定的。因为AOM那篇文章就是这么说的”——说了可以的,就一定可以。没说可以的,未必一定不可以喔。这好象是小学生的逻辑题吧。。。特别是在产品特性介绍文档里。就算是参考文档,也没人会把所有“不可以”的情况的列出来的。遇到一个文档里没提的特性,动手试一下,这是任何一个程序员的基本常识吧。。。就算你不试,最多就不用那个特性了,也不可以基于假设继续往下写程序呀,这可是大错特错的行为呀。但hax兄是基于一些假设用绝对的语气写了一整段文字喔。。。

“我其实还想问,既然不是因为这个原因,那么@BeforeRender有什么用?”,目前按我的理解,就是在这个方法里可以在JSF的Render Response阶段——啊,忘了你不知道——就是一次请求中,所有业务处理已经完毕,IoVC绑定已经完成之后,根据组件模型构建响应结果之前,给一个机会用户插手做点事情。一般来说,希望在IoVC绑定之后对组件树作动态修改的逻辑可以放在这里。

“我来看例子,不是看他的使用方法的。而是要看他的理念。”——你在产品特性介绍文档举的简单例子里,既不看说明文字,又不理解JSF本身的前提下,想看理念,这也就怪不得你会不满意呀。

“请问google这样的ui要IoVC干嘛?它什么web框架都不要,一个最简单的html就完了。捡软柿子捏也没有这样的,我还能说什么呢?” —— 本来上面已经提过,我又怕你又忽略了,重复一下,顺序看下来的其他读者请跳过本段。“BTW那段完全没有看懂,先不妄自推测了。我找你要统计数据是因为你说“展示逻辑变动必然比业务逻辑快”,是要直证(也就是说,要么说出明确的推理,要么举出压倒性的统计数据),我说的是这句话的反面,也就是“不必然”,只需要反证,举了个google足矣,还搭了个MSN,顺带提及了其他电子商务网站。你别管它软不软,反正就说明了“不必然”。”这个其实跟IoVC没什么直接联系,并不是说google就要用IoVC(哪天真的是的话AOM的朋友可记得要请我喝酒了),只是说现实上就存在着展示没什么需求要变的项目。

“他已经有@LiteBean了。”——我也想过让LiteBean具有这样的特性可能挺好,但后来又想事实上有很多LiteBean是带有自己内部用的私有field的,在JSF的编程模型中它还可能要管页面行为。那么不符合这个约定的LiteBean就有可能挺多,正如你所说:“你的约定要是基于过分简化不切实际的假设,那约定得再简单再漂亮也就一个词:意淫。”,所以提建议时保守了点。具体怎样搞请AOM的团队斟酌吧。

“需要么?按照IoVC,一切都绑定又怎么样?你view上没有id不就好了。”—— id除了做IoVC还有可能是css或者javascript的标识呀,而且按照AOM的角色职责,应该是前端人员告诉程序员用了什么id,而不是程序员去告诉前端不准用什么id。这种基本东西AOM还是考虑到的。。。

“我为什么说他心虚,前面已经说得很清楚了,不再赘述”——我为什么说他不心虚,前面已经说得很清楚了,不再赘述。(感觉又回到了充满童真的小学时代。。。)
105 楼 xj4150 2008-03-30  
Annotation在Guice接触过一些
现在就在用operamasks做东西,确实很好用,但不能和其他JSF项目共存于一个服务下让人纳闷!
104 楼 treenode 2008-03-29  
tmj 写道
.net 的webform 不就是这么操作嘛



同意此观点。你们这种做法,实际上跟ASP.NET走的是同一条路子。不过同时大家也知道的是,微软现在已经意识到ASP.NET的结构是有一些问题的,于是又有了ASP.NET MVC,微软正在逐步走回正统框架的路子。这个东西,如果做得好的话,是能够对快速开发起到一定效果,但的确算不上什么新思想了。

我本人对这种思路是比较不感冒的。目前的客户端技术,包括Ajax、Flex和Silverlight,都有一个极大的共同点,即不依赖于特定的服务器端实现,无论 Flex+.Net 或 Silverlight+ROR 的组合都是毫无问题的。表现层技术能够脱离对服务器端编程语言的依赖,独立实现自身的发展变化,我认为是一个很好的现象,也应当是未来的趋势,对于这种试图将表现层纳入服务器语言强力统治版图的实现思路,我认为它是在开历史的倒车。当然这可能也有我自己的一些偏见在里面,算是一家之言吧。
103 楼 hax 2008-03-29  
补充回一下以前帖子与技术关系不大的内容:

1. 为什么要把句子挑出来说。因为辩论要有针对性。无的放矢确实是无敌方式,因为放之四海的空头大话谁都会说。

2. 偶没有光批评,偶也给出了我认为合理一点的做法了。大家对比吧。

3. 为什么要说例子无力?因为举出来的例子真的无力。本来个例就不一定能说明问题,偏偏连个例都举不好……

4. 还有我要的例子是技术例子,不是什么钉子锤子、青蛙烧饼这种。而且如果要说这种,我建议直接一点,咱老祖宗有成语的:“井底之蛙”。不过MVC不是我们扯出来的,是AOM自己硬要扯上去的。前面许多同志只是批评它不要“指鹿为马”而已。

5. 稳定不稳定的问题偶不想扯了,想不通的朋友可以问问袁红岗“表现层稳定还是业务层稳定”?

6. 其他问题有意义的部分前面回答过了。没意义的部分……那自然就不用说了。



xxjhappy 写道
老实说我对这样把贴子拆开来逐句反驳的文体不是太感冒,一来容易断章取义,只注意句子上的不足,而忽略了通篇的重点。二来容易陷入为反驳而反驳的误区,如果一篇文字,只是为了反驳对方,而没有提出自己的观点,是没有什么实质贡献的。有这个闲情不如去多写几行代码了。。。

因此,我想只就你贴子中一些真正涉及到技术的地方展开一下我的看法。对于“为什么例子这么无力”这些见仁见智的东西,就不执着了。读者自然会判断。

关于“前面已经说了,这里谈view/model,只是mvc里的model和view。不要扯到几层service之后的那些model(比如db model?)那里去吧!”(请原谅我也逐句引用,因为原贴就不连贯。。。) 这里我觉得有两个误区,首先我在贴子中说了,IoVC是试图解决一些MVC多年来没有解决的问题。如果一开始就把view/model局限在传统MVC的范围内,传统MVC制定的条条框框看成是至高无上,不容置疑的。也许语气有点重,但我觉得跟下面的情形的确有点相似:很久以前,有只青蛙,觉得天空是个烧饼大的圆圈。那么在他自愿跳出框框之前,是无法去讨论海阔天空的。第二,你引的那一句我所指的结构性变化只在界面,完全没有涉及到n层之后的model。如果不清楚界面的“内容变动”与“结构变动”之间的差别,请参考CMS(内容管理系统)和用户个性化定制的有关资料。

“业务层变化=>业务层到展示层的接口变化,这有必然的因果关系么?如果真的必然变化,那说明什么问题?如果展示层本身真的没有变化的要求,难道不能维持接口不变吗?facade、adapter、proxy、bridge等等都吃干饭的啊?”  这个“难道不能维持啥啥不变吗?”是个自从有软件开发行业以来人人都在问的问题,用瀑布生命周期开发时,人们在问“难道不能维持需求文档不变吗”。做系统整合时,人们在问“难道不能维持遗留系统不变吗” 答案是,当然可以,只是需要付出代价。facade、adapter、proxy、bridge都不是吃干饭的,但如果作为应用设计者,仅仅为了维持需求改变时业务接口不变而去关心这一摊东西,跟业务逻辑有关吗?跟界面设计有关吗?能在交付时跟客户说“我的项目虽然晚了半年,但我在自主开发的代码中用了facade、adapter、proxy、bridge等等模式,保证了模型层接口的稳定性”吗?

“这是因为,展示层确实是比业务层易变。企业应用系统的本质就是如此。”这个东西就不想再展开了,简单提醒一下,你的观点是基于“展示层必定比业务层易变,而且如果使用IoVC,展示层的变动必然传递到模型层”,两者缺一都不足支持你的观点。现在只说前半句,就算我退一步,承认有60%项目展示层比较易变,那么我还有40%的市场。而你则在试图下结论,所有应用的展示层必然比业务层易变,并由此引出后续的论点。。我不知道这有何统计根据或者理论根据。另外我也不知道“本质就是如此”这个定论怎么下的,当年老马为了说明资本主义的本质是剥削剩余价值,可是写了洋洋洒洒一大部《资本论》的。怎么这里一句话就给企业应用的本质定性了。而且我也没说过什么UI,数据源之类的,如果有人说了,那的确是在狡辩,这点我们观点是一致的。

“所以我不知道你这个话是站在什么立场在说,如果你是站在Web框架开发者的角度,那么拜托,这个视角是不同的好不好。” 还是说明了锤子和钉子的问题,view的多样性(一个模型带着多个view)的需求,带来的view与model的分离,产生了希望在model变动时如果不必要就不要影响view的需求,这是整个系统的客观需求,不会以视角为转移的,不会说我拿着UI的锤子,我看到的就都是UI的问题。我强调本帖只针对web,是因为JSF(或者ruby on rails)本来就是个针对web的东西,那么它本身能应付的,就只是web展示。如果考虑其他形式的展示,则必须要考虑web框架以外的东西。那就不在本帖的主题上了。

“为什么不可以?当然可以!只要你的需求是需要做这种抽象的话。"   不知道什么年代起“做抽象”居然变成了需求。你意思是希望客户跟你说,系统的生日字段可能会在三年后能做成多国语言,也可能需要用一个由1990年1月1日起的微秒数来显示,也可能需要做个加密算法,不过也未必一定会这样做噢,现在我只需要一个八位字符能够看出年月日就行了。听完后你就在大展拳脚在生日字段上搞出个抽象层来显示八位字符。看上去不像在做应用,倒像在写框架了。即使是,那么AOM,退一步来说,JSF早帮你把框架做好了。

”请给出“业务层变动比展现层变动快”的例子。“ —— 请给出展示层*必然*比业务层变动快的*统计数据*

”我说的不是这种东西。我说的是组件与数据源绑定。例如<select source="mylist.xml">这类的。" 不好意思,我所说的那些并没有考虑这种状况,这样不经业务层直接在UI绑数据源的做法自从foxpro,vb6就有了,不是说它不好,损誉参半吧,但用在web客户端中好象有点难度,直接绑上去了叫我的控制逻辑和业务放哪里?所以直接忽略了。而且就算考虑了,也不影响原文的论述,道理是一样的。如果你说的组件绑数据源还有什么玄机,请稍微展开说一下。

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

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

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

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

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

这几段是说框架限制的,合起来说吧,很是不习惯逐段割裂的文体。。。如果我告诉你,对了,就是没有限制,你在这里可以可以做任何事,而且很方便。有什么问题?你会说,没有限制,以后变动会很麻烦。但如果我能做到以后变动都很方便呢?当然我不是说IoVC就要做成一个万能的神,但我也没听过有谁会因为“没有限制”去排斥一个框架的,只会因为一个框架为了达到“方便”而引入的诸多限制(包括IoVC也必然有类似的限制)或者转移了的工作量而颇有微词。至于说“什么叫框架。框架就是要给出规约,要强制一些规则。” 这个我看就有点强迫症的迹象了,框架给出规则制约,是因为它给你提供方便的代价。没听过有人仅仅是为了给自己的项目加上规则和限制(注意是开发规则,而不是业务或安全规则)而去引入一个框架的。也许你想说的是编程模型,例如MVC,那么它本来就是个虚的东西,只是告诉你应该这么这么做,否则那么做会如何如何。跟一个具体的框架的所允许的能力根本没有可比性也没有冲突,我在原贴中说过,AOM允许你从bean改变展示,但没有任何人会推荐你这样做,也就是说,AOM也有其应该遵守的编程模型,反其道而行并不一定讨好,但在某些特殊场景,它提供了让你这样做的选择权利。所以我不太热中逐句反驳这种文体,它让人只在意眼前的钉子,而忽略了其他的关键。还有一个明显例子就是“你说的这个跟我直接在网页里内嵌${xxx}有什么区别”,原贴已经专门用一段文字说明了这个跟你直接在网页里内嵌${xxx}有什么区别了,在此就不重复。

关于id,首先我想问下,没事为什么要去变id? 客户会关心id吗?业务逻辑会牵涉到页面id吗?id本来就是个三不管的东西,这种既简单,又跟什么都不耦合的东西,用来作为粘合剂是最合适不过的了。另外如果页面涉及了css和javascript,有谁会有心情没事改变作为DOM标识的id来玩?但如果你说一定要跟我较真,页面里就是有id要不停的变,那么关于这个元素的动态内容,就只好请你老老实实在页面里写EL了。重申一下,框架是为了给人提供方便而存在的,作为代价,你必须要符合它的一些规则。差别只是在于,这个规则是否强加于你,如果你有一天真的需要打破规则,框架是否允许你放弃等量的方便,去换取自由,而没有给你添加任何麻烦?

102 楼 hax 2008-03-29  
1. 偶是没用过AOM,因为我对JSF根本就不感冒。而且我没有必要也没有义务先要用过AOM再去批评它。如果说我看了AOM提供的文档和例子从而以偏概全,那也是AOM自己的问题,为什么它的文档和例子给别人错误的印象呢?实际上,产品的文档反映了他们自己对产品的认知,所以我认为基于此做判断是很正常的。况且我其实已经在努力往好的方面理解了。

2. 我为什么要提“id变”的问题,怎么还不理解内?说的再明白一点,我是点明了一个事实,绑定约定总是存在的。区别是绑定的表达能力如何。框架的作用就是找到一个平衡点,并确保或至少引导开发者始终保持在这个平衡点附近。AOM或许认为el的设计不好,无非是认为网页设计者或曰美工用不来或者根本不应该用el,这种看法或许是有一定道理的,但是可惜的是AOM的同志在这里只是基于一个浮于表面的感觉(当然也许他们有更深入的理解,但是现有的文章是故意写得浅白,从而让我们无缘得知他们的更本质的思考)——比如说,我就可以问,既然认为美工不应该用el,那为什么美工应该用taglib或任何除了html之外的markup?

你还追问id为什么要变,我真的懒得回答了。我就问一下,这里有谁写好java类之后从来不改类名和方法名的?难道就java开发人员掌有“命名”事物的权力,而美工和前端开发者就没有?id可以充当粘合剂不代表id就只是粘合剂。

3. “IoVC与传统JSF的分别,就在于让程序员在java中管理耦合点id,还是由美工在页面去管理el。”

这个总算说到点子上了,AOM的文档如果能大白话的写那么一句,我们就不必浪费那么多眼神和口水了。

我得承认,IoVC是符合一种思路的。这种思路就是,view只是花架子,是美工托托拽拽画出来的,view的本质是不可控的,是obscure的。但是你又要控制它,所以用id打下楔子,然后由java代码灌注意义和灵魂。

就简单的一对一填充数据来说,IoVC完成得非常好,这个不用说了,但是遇到稍微复杂一点的ui logic怎么办?好了,AOM出hack了,第一招叫做attribute侵入,第二招更狠,直接生成一些javascript嵌入进去。我其实还没有提别的问题,比如我一个view上要用一个model的两个不同的instance怎么办?我猜他就是换一个attribute来侵入,或者还有其他狠招。

大家一眼即可以看出这些招实际副作用很大(model这样侵入ui,那能好得了嘛——除非你这个model就是专为view服务的),AOM自己也知道,所以名之曰约定“优于”配置(提醒同学们,我这里的修辞手法叫做“双关”,千万别给认成了“反讽”)。

BTW,我现在挺反感拿约定配置来说事儿的了。你的约定要是基于过分简化不切实际的假设,那约定得再简单再漂亮也就一个词:意淫。我记起有人叫我给“统计数据”,太搞笑了,“统计数据”不问打着所谓“约定配置”旗号的同志要,管我要?我只要求给个像样点的例子,那边倒好,言之凿凿的问我要“统计数据”,我想我真是太善良了点。

言归正传,我们回到IoVC的理念。其实就一个,在AOM眼里,view就是一个架子,根本没有logic的。

这种思路并不是完全没有可取之处,但是IoVC有两个大问题,这说明他们没有把深层次问题想明白,而只顾着所谓“方便”。

第一,就是用java来bind,导致ui的约束崩溃了。虽然他像模像样的说,我们没叫你把style写到bean里——废话,JSP也没叫你把jdbc写到JSP里。事实上,连IoVC自己的例子都被袁老大点评成了“有问题”。AOM自己的人都要用豁边,何况普通开发者?

第二,抛开前面这种情况,我们假设IoVC是把与纯粹的ui控件(空架子)无关的部分解耦出来了,放到了model里。问题来了,你的model到底是什么model?

我随手写的例子其实就是要说明这个问题,解耦有很多方法,但是我的方式是有约束的(我采用了定义好的xml tag,同时既有的el也是一个约束,他阻止了我在这里写jdbc——当然也可以用其他方式约束),那就是model是view的model,它是从属于view的。而IoVC就没有这种约束了。AOM有一个名头是@LiteBean,这说明他们认为这个东西应该是lite的,但是他们没有意识到的(或者他们偷偷藏起来没告诉我们的)是,从ui解耦出来的所有“绑定”都应该是从属于view的。如果他们意识到这一点的话就应该把这个命名为ViewBean或者干脆FormBean。

这两个错误归根到底都是缺乏约束。或者再说得玄虚一点,就是缺乏合理的philosophy。什么都可以实际上就是什么都不可以。

4. 关于我随手写的例子。

“同一个view里无端的多出一个间接绑定,仅仅是把el堆到一起,有什么实际意义呢。”

有什么意义,意义就是达到IoVC所希望达到的别让el去烦美工的想法。用术语来说,就是隔离ui控件和所需的数据源、action等。

但是,不同于IoVC的有三点,第一,我明确这是view的一部分;第二,我不会打破ui约束(代码里没有完全表现出来,但是可以说一下,我不会允许所有的markup都能binding,bind属性只能用于特定的markup);第三我保持了bind的灵活性,但是又不至于无法无天(谢谢你告诉我@Bind可以绑方法,我终于可以写jdbc啦!)。

“难道同一个文件头部和正文由不同人去编写?cvs里的冲突警告可不是用来看着好玩的”

当然可以由不同的人去写。逻辑隔离不代表物理上一定要分离。关于CVS,无语了。不同的人写不同部分如果会产生conflict,那要CVS干嘛???

“也许这里也只是举了个不恰当的例子,在真实应用中,你会把例子中model的定义部分分开”

我的例子没有任何不恰当。model是不是要分在一个独立的物理文件里,是由实际需求和团队分工所决定的。

甚至,如果是我写ui,而且ui需要的bean都简单得跟IoVC的例子那样,我根本不会把bind单独写到model部分里,而会直接在markup上用el。只有ui涉及的数据源较为复杂,我才会用bind来映射,以便提高可维护性。

“欢迎你加入IoVC的大家庭,这正是IoVC在做的事。”

IoVC或许想做这个事,可是做得不得法。等他做得法了,我再加入“大家庭”不迟。

“唯一不同的是,IoVC的绑定使用了你认为一定会变的id,而你的例子使用了一个红色的bind属性,这个实现细节我看来是无伤大雅的,只要你说明了为何 id一定会变,有理有据的话,我想AOM的开发人员可以接受改用另外一个随便什么名称的属性来作为耦合点,这应该是举手之劳。”

这根本不是实现细节的问题。

应该在ui control上用bind属性去绑定bean的实例,而不能反过来让java class去根据id填充ui control。最简单的例子:两个ui control绑定相同的bean,难道你要他们有相同的id?好,你说我换一个属性,比如class吧。那我另十个页面上已经用id绑定了耶,怎么办(还认为这是“举手之劳”)?如果两个ui control要绑定相同bean的不同实例又怎么办?

“能在模型端享受强类型检查的做法是退化,你的model文件要写个无编译期检查的接口签名还要写个id的做法是进化,没想通,希望能展开论述一下。”

我说的退化是IoVC的类没有规约,回到了洪荒状态。强类型检查很了不起吗?虚幻假象!你是不是一并检查一下你的html里的id拼对没有呢?想想吧,这个根本不可能,你怎么知道我写了一个id是为了给你IoVC来侵入的,还是派别的用场的?你的耦合点根本就脆弱不堪。

相反,我的随意的例子里,是可以通过工具检查出bind的有效性的。如果bind属性和bind元素的id匹配不上,就说明有错误。el也是可以检查有效性的。

“看来hax兄确实是忙于发贴,没闲工夫去下载个AOM试用一下。”

光看光鲜文档就有许多问题,你说我干嘛要去试用它?

“又用了@BeforeRender来对result赋值,就断定IoVC只能绑field”

我确实是这样推定的。因为AOM那篇文章就是这么说的。

“在AOM 2.0下,连 setter/getter 方法都没有?是的,完全可以忽略。……那么,result 的值是在哪里设置的?请注意 settingValues 方法,它有一个 @BeforeRender 的声明”

你说我不相信他们自己的文档还要相信什么呢?

如果说可用get/set,为什么不写成getResult()呢,难道就是为了拽一拽一个叫做@BeforeRender的莫名其妙的annotation?我其实还想问,既然不是因为这个原因,那么@BeforeRender有什么用?

“hax兄看待例子的态度,好象与一般人大相径庭呀,这也就难怪AOM的同志们举不出令你满意的例子呀。”

我来看例子,不是看他的使用方法的。而是要看他的理念。如果你认为这是大相径庭,那也没办法。

例子很糟好像也不是AOM的专利,前面所谓“google的ui不变”的例子,就实在让人很无语。请问google这样的ui要IoVC干嘛?它什么web框架都不要,一个最简单的html就完了。捡软柿子捏也没有这样的,我还能说什么呢?

-------以下是无关紧要的部分--------------

“让@Bind可以打在类上,打了@Bind的类,如果内部没有使用任何field级的@Bind标注,则默认所有域是绑定域。”

他已经有@LiteBean了。

“如果任何东西都约定默认绑定,那么难道我要配置时,要把所有不绑定的东西都打个@NotBind标注?”

需要么?按照IoVC,一切都绑定又怎么样?你view上没有id不就好了。反正IoVC的说辞就是“约定优于配置”。

“更好的判别策略?愿闻其详。”

不需要(见上一段),或者public/private。反正说到“约定优于配置”我就发笑。

我为什么说他心虚,前面已经说得很清楚了,不再赘述。
101 楼 nwangwei 2008-03-29  
给正下名,包装一个概念也蛮好的,哈哈
100 楼 xxjhappy 2008-03-29  
既然hax兄已经提出了要不吝赐教,我想是却之不恭了。那么请问做前端的hax同志,可不可以具体说说id为什么一定要变呢?弱弱的说,的确不太领会你为什么要提这个问题。。。

耦合点肯定是会有的,正如面向对象思想一直强调将判断结构转化为多态结构,但多态能不能彻底消除判断?不可能,它只能将判断结构前移到创建期。那么你能说多态没有用吗?问题的重点不在于有无,而在于位置与形式。IoVC与传统JSF的分别,就在于让程序员在java中管理耦合点id,还是由美工在页面去管理el。至于两者有什么区别,不想重复了,在第一条回贴里已经说过。如果考虑到一model带多view的情况,还多了个把耦合点集中起来的好处。

hax兄一直对AOM的同志举的例子很不满意,自己随手举了个例子,却真的很随手。想问下这样在同一个view里无端的多出一个间接绑定,仅仅是把el堆到一起,有什么实际意义呢。难道同一个文件头部和正文由不同人去编写?cvs里的冲突警告可不是用来看着好玩的。。。也许这里也只是举了个不恰当的例子,在真实应用中,你会把例子中model的定义部分分开,正如你所说“放在一个model中,注意这个model是该view所专属的model(尽管理论上可以复用),而与mvc里的那个model有所不同。view的model格式可以是xml或其他某种自定义格式的,用java也成”,欢迎你加入IoVC的大家庭,这正是IoVC在做的事。唯一不同的是,IoVC的绑定使用了你认为一定会变的id,而你的例子使用了一个红色的bind属性,这个实现细节我看来是无伤大雅的,只要你说明了为何id一定会变,有理有据的话,我想AOM的开发人员可以接受改用另外一个随便什么名称的属性来作为耦合点,这应该是举手之劳。

至于为什么IoVC直接在java bean中需要绑定的地方打标注,能在模型端享受强类型检查的做法是退化,你的model文件要写个无编译期检查的接口签名还要写个id的做法是进化,没想通,希望能展开论述一下。也没看出明确规约了什么。。。规约了美工必须手工核对签名拼写吗?

“本来如果你聪明点儿,允许get/set方法,那还能恢复等同于el的能力”,据我所知,IoVC是可以绑getter/setter的,句中的“本来如果”可以删掉了。另外因为这句话我可有两句要对hax兄说了,首先看来hax兄确实是忙于发贴,没闲工夫去下载个AOM试用一下。以至于看到例子里没有绑getter,又用了@BeforeRender来对result赋值,就断定IoVC只能绑field,这老实说可不是好的治学态度喔。第二hax兄看待例子的态度,好象与一般人大相径庭呀,这也就难怪AOM的同志们举不出令你满意的例子呀。一般人写文章,是以文字说理,辅以简单例子说明,有时为了配合文字,例子可能会故意走点弯路来展示特性;hax兄看文章,是忽略大段文字,只看某些句子,然后根据例子去发挥天马行空的想象……我明明在第一条回贴里说过:“一个组件id,可以帮在简单的对象域上,也可以绑在public String getPersonName()上。”,看来又是被直接忽略了。但我也觉得目前AOM的示例的确比较单薄,希望开发团队能在AOM2.0正式版发布后,能放出一些足够复杂,模拟真实场景的事例。

文中的顺便一提部分,我觉得挺好,提出了一些实现上的问题。建议AOM团队有则改之无则加勉。但其中一些细节还比较模糊,希望hax兄能展开探讨一下:

关于“AOM实际是把绑定事件的模式套用到了绑定数据上”,这句话老实说我没理解,因为对ASP.NET不熟,就算真是这样,会导致什么问题吗?从这句话后面的叹号来看,似乎是有点问题的。能不能具体说说绑定事件的模式和绑定数据的模式有什么差别,为什么套用会有问题呢?

hax兄对于增加约定规则,减少annotation的建议,我觉得挺好,例如可以考虑参考webservice的@WebMethod标注的做法,让@Bind可以打在类上,打了@Bind的类,如果内部没有使用任何field级的@Bind标注,则默认所有域是绑定域。请AOM团队考虑一下。但说到“不应该要annotation”,我觉得就有点冒失了,如果任何东西都约定默认绑定,那么难道我要配置时,要把所有不绑定的东西都打个@NotBind标注?或者hax兄事实上是说有更好的判别策略?愿闻其详。

关于例子和引文笔者的最后那句话,只是说出了基于Observer模式的事件机制的一个共性。这里可以引用马大叔的一段话来说明:“The great strength, and weakness, of observer is that control passes from the subject to the observer implicitly. You can't tell by reading code that an observer is going to fire, the only way you can see what's happening is to use a debugger. As a result of a complex chain of observers can be a nightmare to figure out, change, or debug as actions trigger other actions with little indication why. ”( http://martinfowler.com/eaaDev/OrganizingPresentations.html )。我觉得对于初学者,是句温馨提示。对于如hax兄般的高手,可能就是既没错但也没很多新意。但不知道跟心虚有什么关系。产品特性介绍文章中的例子,是用来辅助文字的,不是用来代替文字的,也不是用来教你在真实应用中如何选择解决方案的。当然,如果能举出一个真实场景下的简单例子自然最好,但对于事件这种只有在复杂场景下才显出其优势的东西,不举出个四五页的例子就是心虚了吗?其实也未必。。。但不管怎样,至少说明目前大家对例子的需求,还是希望AOM开发团队能发布更多高质素的示例。
99 楼 hax 2008-03-28  
我今天又把AOM的那几篇讲IoVC的文章看了一遍。我的判断没有改变,IoVC的出发点是好的,但是设计思路有问题。

下面简单的说一下。

http://www.operamasks.org/articles/iovc/html_single 这篇文章(也就是顶楼)我就不说了,因为袁老大说这个文章举例不妥。而且前面几位也一再强调给你刀不是鼓励你杀人,所以我就不追打了。

所以我来分析http://www.operamasks.org/articles/helloduck-iovc/html_single 这个。

在这个例子中,view中的差异在哪里?其实就是el被换成了id。

java类的差异在哪里?
这个java类原来包含了data和action。其中result是依赖其他数据状态的。
而AOM改成了java类的field到markup的binding。此外result被改成了基于事件填充数据。

而这两个改变都是有问题的。

第一个el换成id。AOM的出发点是避免页面中嵌入所谓“代码”。想法虽好,但是用力用错了地方。如果说el会被滥用,那IoVC更会被滥用。在这里不应该执行双重标准。

如果说希望el不要骚扰金贵的美工同志。这我完全可以理解。但是,请注意,就算你用id,你至少有一个耦合点。那么id表示什么?其实就表示一个绑定约定。这就是我前面问id的原因,可惜前面的同志说了一大堆id不用变的理由((况且就站不住脚,请问问做前端的同志为什么要改id吧),看来完全不领会我为什么提这个问题。

如果理解了绑定约定的问题,就知道要解决这个问题根本无需引入什么IoVC,你只需要定义一个bind到el的映射就好了。这个映射可以写在view中,隔离在一个单独的tag中,也可以跟view独立开来,放在一个model中,注意这个model是该view所专属的model(尽管理论上可以复用),而与mvc里的那个model有所不同。view的model格式可以是xml或其他某种自定义格式的,用java也成,但是我认为没有必要。例如可以随手设计这样的标签:
<html
xmlns:v="http://example.hax.iteye.com/mvc/view"
xmlns:ui="http://example.hax.iteye.com/mvc/ui-controls">
<head>
<v:model>
<v:instance id="user" type="com.javaeye.hax.example.UserBean"/>
<v:bind id="first-name" el="${user.firstName}"/>
<v:bind id="last-name" el="${user.lastName}"/>
...
</v:model>
</head>
<body>
...
<ui:input>
  <ui:label>First name</ui:label>
  <ui:value bind="#first-name"/>
</ui:input>
<ui:input>
  <ui:label>Last name</ui:label>
  <ui:value bind="#last-name"/>
</ui:input>
...
</body>
</html>


其中<v:model/>部分也可以发挥所谓“配置优于约定”,如果view是*.html那就放到*.model文件中。

从这个角度说,IoVC下的java类其实是用java写的,进一步退化的model文件。但是它缺乏了像我这里的model文件那样明确的规约!我强调说框架的价值就在规约,有人不以为然,那我也没办法,各位请自行体会好了。

退一步,我们不考虑因缺乏规约而导致的问题,我们就看等价于退化的用于view的model的AOM中的java类。

我们注意到el被干掉了,你只有平面的field,而失去了灵活的el的层次性。这样扁平的java类真是连json都不如,何况xml?本来如果你聪明点儿,允许get/set方法,那还能恢复等同于el的能力,现在只能变成干巴巴的,要稍微复杂点的(比如result那个)就只好搞成beforeRender之前去赋值一下——自找麻烦。

下面顺便说说其他一些问题。

Apusic Studio的支持,乍看之下貌似是类似ASP.NET的code behind,本身没啥好说的。但是各位看官可以注意到了,这实际上告诉我们一个信号,即AOM实际是把绑定事件的模式套用到了绑定数据上!

下面我们再看http://www.operamasks.org/articles/magic-1/html_single

对于所谓配置优于约定,我先不予置评。但是明显如果按照这个理念,连annotation都不应该要。field就是数据bind,method就是action。但是诸位,不要以为我是在开玩笑,我是说真的。

再看AOM的模型事件:http://www.operamasks.org/articles/magic-4/html_single

他最后一句话是“笔者以为:事件是一把双刃剑,运用得好,那么,能够大大增强程序的灵活性及可扩展性; 但如果滥用事件,则只会让你的程序难以跟踪,难以理解。”

这个其实就心虚了,因为他文中所举的例子其实在真实应用中肯定会用集中的规则触发机制来做,而绝不会分散在各个bean里写什么事件。姑且认为又是举例无力。

AOM的同志们,难道你们不能加把劲,举个好点的例子吗?还是说举来举去就是这样了呢?
98 楼 tmj 2008-03-28  
.net 的webform 不就是这么操作嘛
97 楼 dboylx 2008-03-28  
xxjhappy 写道
哇,hax兄对技术的热情真是令人佩服。我昨晚2点写的贴,你是4点钟回的贴。。。技术固然重要,也要注意休息喔。

老实说我对这样把贴子拆开来逐句反驳的文体不是太感冒,一来容易断章取义,只注意句子上的不足,而忽略了通篇的重点。二来容易陷入为反驳而反驳的误区,如果一篇文字,只是为了反驳对方,而没有提出自己的观点,是没有什么实质贡献的。有这个闲情不如去多写几行代码了。。。

因此,我想只就你贴子中一些真正涉及到技术的地方展开一下我的看法。对于“为什么例子这么无力”这些见仁见智的东西,就不执着了。读者自然会判断。

关于“前面已经说了,这里谈view/model,只是mvc里的model和view。不要扯到几层service之后的那些model(比如db model?)那里去吧!”(请原谅我也逐句引用,因为原贴就不连贯。。。) 这里我觉得有两个误区,首先我在贴子中说了,IoVC是试图解决一些MVC多年来没有解决的问题。如果一开始就把view/model局限在传统MVC的范围内,传统MVC制定的条条框框看成是至高无上,不容置疑的。也许语气有点重,但我觉得跟下面的情形的确有点相似:很久以前,有只青蛙,觉得天空是个烧饼大的圆圈。那么在他自愿跳出框框之前,是无法去讨论海阔天空的。第二,你引的那一句我所指的结构性变化只在界面,完全没有涉及到n层之后的model。如果不清楚界面的“内容变动”与“结构变动”之间的差别,请参考CMS(内容管理系统)和用户个性化定制的有关资料。

“业务层变化=>业务层到展示层的接口变化,这有必然的因果关系么?如果真的必然变化,那说明什么问题?如果展示层本身真的没有变化的要求,难道不能维持接口不变吗?facade、adapter、proxy、bridge等等都吃干饭的啊?”  这个“难道不能维持啥啥不变吗?”是个自从有软件开发行业以来人人都在问的问题,用瀑布生命周期开发时,人们在问“难道不能维持需求文档不变吗”。做系统整合时,人们在问“难道不能维持遗留系统不变吗” 答案是,当然可以,只是需要付出代价。facade、adapter、proxy、bridge都不是吃干饭的,但如果作为应用设计者,仅仅为了维持需求改变时业务接口不变而去关心这一摊东西,跟业务逻辑有关吗?跟界面设计有关吗?能在交付时跟客户说“我的项目虽然晚了半年,但我在自主开发的代码中用了facade、adapter、proxy、bridge等等模式,保证了模型层接口的稳定性”吗?

“这是因为,展示层确实是比业务层易变。企业应用系统的本质就是如此。”这个东西就不想再展开了,简单提醒一下,你的观点是基于“展示层必定比业务层易变,而且如果使用IoVC,展示层的变动必然传递到模型层”,两者缺一都不足支持你的观点。现在只说前半句,就算我退一步,承认有60%项目展示层比较易变,那么我还有40%的市场。而你则在试图下结论,所有应用的展示层必然比业务层易变,并由此引出后续的论点。。我不知道这有何统计根据或者理论根据。另外我也不知道“本质就是如此”这个定论怎么下的,当年老马为了说明资本主义的本质是剥削剩余价值,可是写了洋洋洒洒一大部《资本论》的。怎么这里一句话就给企业应用的本质定性了。而且我也没说过什么UI,数据源之类的,如果有人说了,那的确是在狡辩,这点我们观点是一致的。

“所以我不知道你这个话是站在什么立场在说,如果你是站在Web框架开发者的角度,那么拜托,这个视角是不同的好不好。” 还是说明了锤子和钉子的问题,view的多样性(一个模型带着多个view)的需求,带来的view与model的分离,产生了希望在model变动时如果不必要就不要影响view的需求,这是整个系统的客观需求,不会以视角为转移的,不会说我拿着UI的锤子,我看到的就都是UI的问题。我强调本帖只针对web,是因为JSF(或者ruby on rails)本来就是个针对web的东西,那么它本身能应付的,就只是web展示。如果考虑其他形式的展示,则必须要考虑web框架以外的东西。那就不在本帖的主题上了。

“为什么不可以?当然可以!只要你的需求是需要做这种抽象的话。"   不知道什么年代起“做抽象”居然变成了需求。你意思是希望客户跟你说,系统的生日字段可能会在三年后能做成多国语言,也可能需要用一个由1990年1月1日起的微秒数来显示,也可能需要做个加密算法,不过也未必一定会这样做噢,现在我只需要一个八位字符能够看出年月日就行了。听完后你就在大展拳脚在生日字段上搞出个抽象层来显示八位字符。看上去不像在做应用,倒像在写框架了。即使是,那么AOM,退一步来说,JSF早帮你把框架做好了。

”请给出“业务层变动比展现层变动快”的例子。“ —— 请给出展示层*必然*比业务层变动快的*统计数据*

”我说的不是这种东西。我说的是组件与数据源绑定。例如<select source="mylist.xml">这类的。" 不好意思,我所说的那些并没有考虑这种状况,这样不经业务层直接在UI绑数据源的做法自从foxpro,vb6就有了,不是说它不好,损誉参半吧,但用在web客户端中好象有点难度,直接绑上去了叫我的控制逻辑和业务放哪里?所以直接忽略了。而且就算考虑了,也不影响原文的论述,道理是一样的。如果你说的组件绑数据源还有什么玄机,请稍微展开说一下。

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

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

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

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

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

这几段是说框架限制的,合起来说吧,很是不习惯逐段割裂的文体。。。如果我告诉你,对了,就是没有限制,你在这里可以可以做任何事,而且很方便。有什么问题?你会说,没有限制,以后变动会很麻烦。但如果我能做到以后变动都很方便呢?当然我不是说IoVC就要做成一个万能的神,但我也没听过有谁会因为“没有限制”去排斥一个框架的,只会因为一个框架为了达到“方便”而引入的诸多限制(包括IoVC也必然有类似的限制)或者转移了的工作量而颇有微词。至于说“什么叫框架。框架就是要给出规约,要强制一些规则。” 这个我看就有点强迫症的迹象了,框架给出规则制约,是因为它给你提供方便的代价。没听过有人仅仅是为了给自己的项目加上规则和限制(注意是开发规则,而不是业务或安全规则)而去引入一个框架的。也许你想说的是编程模型,例如MVC,那么它本来就是个虚的东西,只是告诉你应该这么这么做,否则那么做会如何如何。跟一个具体的框架的所允许的能力根本没有可比性也没有冲突,我在原贴中说过,AOM允许你从bean改变展示,但没有任何人会推荐你这样做,也就是说,AOM也有其应该遵守的编程模型,反其道而行并不一定讨好,但在某些特殊场景,它提供了让你这样做的选择权利。所以我不太热中逐句反驳这种文体,它让人只在意眼前的钉子,而忽略了其他的关键。还有一个明显例子就是“你说的这个跟我直接在网页里内嵌${xxx}有什么区别”,原贴已经专门用一段文字说明了这个跟你直接在网页里内嵌${xxx}有什么区别了,在此就不重复。

关于id,首先我想问下,没事为什么要去变id? 客户会关心id吗?业务逻辑会牵涉到页面id吗?id本来就是个三不管的东西,这种既简单,又跟什么都不耦合的东西,用来作为粘合剂是最合适不过的了。另外如果页面涉及了css和javascript,有谁会有心情没事改变作为DOM标识的id来玩?但如果你说一定要跟我较真,页面里就是有id要不停的变,那么关于这个元素的动态内容,就只好请你老老实实在页面里写EL了。重申一下,框架是为了给人提供方便而存在的,作为代价,你必须要符合它的一些规则。差别只是在于,这个规则是否强加于你,如果你有一天真的需要打破规则,框架是否允许你放弃等量的方便,去换取自由,而没有给你添加任何麻烦?



JAVAEYE上能一贴写这么多字的人不多~~
96 楼 xxjhappy 2008-03-28  
dualface 写道
用户界面如何呈现、对于事件如何响应,本来就是应用程序逻辑的一部分。根本不应该放到 M 中去实现。

要在服务端响应 UI 事件,并改变 UI,最好的途径还是事件驱动机制。


如果一定要套上MVC来理解IoVC(或者说理解JSF),我觉得应该是这样的,View还是View,Model还是Model,Controller则是由页面Bean和UI组件模型类共同构成的。那么IoVC事实上是把代码中定义绑定的位置与定义行为的位置放到了Controller中。(楼上许多误区是把JSF框架看成controller,而把页面bean和UI组件类看成不伦不类的模型。这就等于把struct框架看成controller,把用户定义的action类看成模型一样别扭)

这与MVC是不矛盾的,特别地,与hax兄在楼上多次提起的smalltalk形式的MVC,有着异曲同弓之妙。MVC的原本定义,是在展示层极其单薄的情况下,所有行为(包括最初接受键盘输入这种行为)都放在controller层,然后由它去调用展示逻辑进行展示。也就是说,view只管自己(其实没什么管可言,它里面没有任何实质逻辑,只负责把自己画出来),model也只管自己,controller两边都管。但发展到web编程,这样的MVC模式是很难组织起来的,因为controller部署在服务器端,不可能直接接触到行为的发起者(例如接收键盘输入),那么必然导致了view层需要负担起调用controller的任务,形成了View同时依赖于Model与Controller的现状。这也就造成了人们认为Model相对稳定,View必然不稳定的错觉,原因很简单,Model改变时View和Controller要变,Controller改变时View要变,View改变时就不用说了。那么IoVC做的其实是,把View对Controller的依赖还原到Controller对View的依赖(而且是通过id来绑定的非常弱的依赖),而View只关心自己的展示。

至于事件,JSF本来就是基于事件的,而且AOM对JSF的标准事件机制进行了增强。

顺带一提,马大叔在06年好象试图出一本EAA续集,但不知道后来为啥不了了之了,现在马大叔好象在潜心搞领域特定语言了。但他当时的文稿还挂在网上,其中有几篇对MVC的前世今生作了通俗易懂的介绍(马大叔的一贯风格),有兴趣的朋友可以去看看:

项目主页:《Development of Further Patterns of Enterprise Application Architecture》 http://martinfowler.com/eaaDev/

如何组织展示逻辑:http://martinfowler.com/eaaDev/OrganizingPresentations.html

GUI架构(此文对MVC进行了详述):http://martinfowler.com/eaaDev/uiArchs.html
95 楼 xxjhappy 2008-03-28  
哇,hax兄对技术的热情真是令人佩服。我昨晚2点写的贴,你是4点钟回的贴。。。技术固然重要,也要注意休息喔。

老实说我对这样把贴子拆开来逐句反驳的文体不是太感冒,一来容易断章取义,只注意句子上的不足,而忽略了通篇的重点。二来容易陷入为反驳而反驳的误区,如果一篇文字,只是为了反驳对方,而没有提出自己的观点,是没有什么实质贡献的。有这个闲情不如去多写几行代码了。。。

因此,我想只就你贴子中一些真正涉及到技术的地方展开一下我的看法。对于“为什么例子这么无力”这些见仁见智的东西,就不执着了。读者自然会判断。

关于“前面已经说了,这里谈view/model,只是mvc里的model和view。不要扯到几层service之后的那些model(比如db model?)那里去吧!”(请原谅我也逐句引用,因为原贴就不连贯。。。) 这里我觉得有两个误区,首先我在贴子中说了,IoVC是试图解决一些MVC多年来没有解决的问题。如果一开始就把view/model局限在传统MVC的范围内,传统MVC制定的条条框框看成是至高无上,不容置疑的。也许语气有点重,但我觉得跟下面的情形的确有点相似:很久以前,有只青蛙,觉得天空是个烧饼大的圆圈。那么在他自愿跳出框框之前,是无法去讨论海阔天空的。第二,你引的那一句我所指的结构性变化只在界面,完全没有涉及到n层之后的model。如果不清楚界面的“内容变动”与“结构变动”之间的差别,请参考CMS(内容管理系统)和用户个性化定制的有关资料。

“业务层变化=>业务层到展示层的接口变化,这有必然的因果关系么?如果真的必然变化,那说明什么问题?如果展示层本身真的没有变化的要求,难道不能维持接口不变吗?facade、adapter、proxy、bridge等等都吃干饭的啊?”  这个“难道不能维持啥啥不变吗?”是个自从有软件开发行业以来人人都在问的问题,用瀑布生命周期开发时,人们在问“难道不能维持需求文档不变吗”。做系统整合时,人们在问“难道不能维持遗留系统不变吗” 答案是,当然可以,只是需要付出代价。facade、adapter、proxy、bridge都不是吃干饭的,但如果作为应用设计者,仅仅为了维持需求改变时业务接口不变而去关心这一摊东西,跟业务逻辑有关吗?跟界面设计有关吗?能在交付时跟客户说“我的项目虽然晚了半年,但我在自主开发的代码中用了facade、adapter、proxy、bridge等等模式,保证了模型层接口的稳定性”吗?

“这是因为,展示层确实是比业务层易变。企业应用系统的本质就是如此。”这个东西就不想再展开了,简单提醒一下,你的观点是基于“展示层必定比业务层易变,而且如果使用IoVC,展示层的变动必然传递到模型层”,两者缺一都不足支持你的观点。现在只说前半句,就算我退一步,承认有60%项目展示层比较易变,那么我还有40%的市场。而你则在试图下结论,所有应用的展示层必然比业务层易变,并由此引出后续的论点。。我不知道这有何统计根据或者理论根据。另外我也不知道“本质就是如此”这个定论怎么下的,当年老马为了说明资本主义的本质是剥削剩余价值,可是写了洋洋洒洒一大部《资本论》的。怎么这里一句话就给企业应用的本质定性了。而且我也没说过什么UI,数据源之类的,如果有人说了,那的确是在狡辩,这点我们观点是一致的。

“所以我不知道你这个话是站在什么立场在说,如果你是站在Web框架开发者的角度,那么拜托,这个视角是不同的好不好。” 还是说明了锤子和钉子的问题,view的多样性(一个模型带着多个view)的需求,带来的view与model的分离,产生了希望在model变动时如果不必要就不要影响view的需求,这是整个系统的客观需求,不会以视角为转移的,不会说我拿着UI的锤子,我看到的就都是UI的问题。我强调本帖只针对web,是因为JSF(或者ruby on rails)本来就是个针对web的东西,那么它本身能应付的,就只是web展示。如果考虑其他形式的展示,则必须要考虑web框架以外的东西。那就不在本帖的主题上了。

“为什么不可以?当然可以!只要你的需求是需要做这种抽象的话。"   不知道什么年代起“做抽象”居然变成了需求。你意思是希望客户跟你说,系统的生日字段可能会在三年后能做成多国语言,也可能需要用一个由1990年1月1日起的微秒数来显示,也可能需要做个加密算法,不过也未必一定会这样做噢,现在我只需要一个八位字符能够看出年月日就行了。听完后你就在大展拳脚在生日字段上搞出个抽象层来显示八位字符。看上去不像在做应用,倒像在写框架了。即使是,那么AOM,退一步来说,JSF早帮你把框架做好了。

”请给出“业务层变动比展现层变动快”的例子。“ —— 请给出展示层*必然*比业务层变动快的*统计数据*

”我说的不是这种东西。我说的是组件与数据源绑定。例如<select source="mylist.xml">这类的。" 不好意思,我所说的那些并没有考虑这种状况,这样不经业务层直接在UI绑数据源的做法自从foxpro,vb6就有了,不是说它不好,损誉参半吧,但用在web客户端中好象有点难度,直接绑上去了叫我的控制逻辑和业务放哪里?所以直接忽略了。而且就算考虑了,也不影响原文的论述,道理是一样的。如果你说的组件绑数据源还有什么玄机,请稍微展开说一下。

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

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

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

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

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

这几段是说框架限制的,合起来说吧,很是不习惯逐段割裂的文体。。。如果我告诉你,对了,就是没有限制,你在这里可以可以做任何事,而且很方便。有什么问题?你会说,没有限制,以后变动会很麻烦。但如果我能做到以后变动都很方便呢?当然我不是说IoVC就要做成一个万能的神,但我也没听过有谁会因为“没有限制”去排斥一个框架的,只会因为一个框架为了达到“方便”而引入的诸多限制(包括IoVC也必然有类似的限制)或者转移了的工作量而颇有微词。至于说“什么叫框架。框架就是要给出规约,要强制一些规则。” 这个我看就有点强迫症的迹象了,框架给出规则制约,是因为它给你提供方便的代价。没听过有人仅仅是为了给自己的项目加上规则和限制(注意是开发规则,而不是业务或安全规则)而去引入一个框架的。也许你想说的是编程模型,例如MVC,那么它本来就是个虚的东西,只是告诉你应该这么这么做,否则那么做会如何如何。跟一个具体的框架的所允许的能力根本没有可比性也没有冲突,我在原贴中说过,AOM允许你从bean改变展示,但没有任何人会推荐你这样做,也就是说,AOM也有其应该遵守的编程模型,反其道而行并不一定讨好,但在某些特殊场景,它提供了让你这样做的选择权利。所以我不太热中逐句反驳这种文体,它让人只在意眼前的钉子,而忽略了其他的关键。还有一个明显例子就是“你说的这个跟我直接在网页里内嵌${xxx}有什么区别”,原贴已经专门用一段文字说明了这个跟你直接在网页里内嵌${xxx}有什么区别了,在此就不重复。

关于id,首先我想问下,没事为什么要去变id? 客户会关心id吗?业务逻辑会牵涉到页面id吗?id本来就是个三不管的东西,这种既简单,又跟什么都不耦合的东西,用来作为粘合剂是最合适不过的了。另外如果页面涉及了css和javascript,有谁会有心情没事改变作为DOM标识的id来玩?但如果你说一定要跟我较真,页面里就是有id要不停的变,那么关于这个元素的动态内容,就只好请你老老实实在页面里写EL了。重申一下,框架是为了给人提供方便而存在的,作为代价,你必须要符合它的一些规则。差别只是在于,这个规则是否强加于你,如果你有一天真的需要打破规则,框架是否允许你放弃等量的方便,去换取自由,而没有给你添加任何麻烦?
94 楼 sxsxsx3 2008-03-28  
dualface 写道
用户界面如何呈现、对于事件如何响应,本来就是应用程序逻辑的一部分。根本不应该放到 M 中去实现。

要在服务端响应 UI 事件,并改变 UI,最好的途径还是事件驱动机制。


看sun的jsf介绍,不是说jsf其中一个亮点就是事件驱动么?类似swing的。
93 楼 onlyerlee 2008-03-28  
这事实上把展现层的表现形式放到逻辑层里面去做,我觉得是违背了MVC原则的。
92 楼 dualface 2008-03-28  
hax 写道
我说说我理想中的企业应用的MVC的形式。

企业应用的特点就是form多。绝大多数交互场景都可以归纳为填form,submission,然后得到report。

当然我有些过度简化(我们有很多周边需求,比如搜索、集成Email、sms诸如此类),另外总是还有导航和portal,这可以视作一个单独的问题。去掉这些,大多数企业应用中的各种业务管理的功能所需的web交互差不多就是这样的。

C这里需要控制所有这些form和submission(action)的flow。这里要解决无状态的问题。

所以比较理想化的分析就是这样:

用户请求一个特定任务,则C先找到该任务的flow,然后找到flow中与当前状态所对应的form(view)。view内会通过某种机制(通常就是URI)绑定许多数据实例。注意这里不应由C直接去填充数据给UI组件,应该由view声明其所需的数据源,并由view自己把从数据源得到的数据实例和view中的UI组件绑定起来。这样才是UI归UI,app归app。这里是松耦合的,M和C都不知道V中的UI细节。

其他部分与现在的web MVC基本相同。比如当V提交了数据到C时(与现在已有的方式一样,这里的action分派由submission指定,但C也可以进一步分派),C执行app logic,处理传入的数据,如调用service,更新model,选择下一个view等等。

在这样的模型里,绑定是发生在UI组件和model的instance之间的,通过基于某种表达式语言灵活的绑定(你也可以坚持只用id绑定,但是显然这是作茧自缚),我们就解耦了ui和model。而且UI可以是抽象UI,即我们可以进一步解耦UI模型和UI的具体形式。这里需要强调一点,解耦程度有多高,关键不在于你用id绑定还是用el(因为model你是可以自行规约简化的),而是取决于UI组件的能力。UI组件对于model的假设和限制就越小,与model的耦合程度自然就越低。这就是我为什么说V越强大MVC越强大。



实际上就是事件驱动机制了。用户界面在服务端有一个对应的对象体系。
91 楼 dualface 2008-03-28  
用户界面如何呈现、对于事件如何响应,本来就是应用程序逻辑的一部分。根本不应该放到 M 中去实现。

要在服务端响应 UI 事件,并改变 UI,最好的途径还是事件驱动机制。
90 楼 hax 2008-03-28  
我说说我理想中的企业应用的MVC的形式。

企业应用的特点就是form多。绝大多数交互场景都可以归纳为填form,submission,然后得到report。

当然我有些过度简化(我们有很多周边需求,比如搜索、集成Email、sms诸如此类),另外总是还有导航和portal,这可以视作一个单独的问题。去掉这些,大多数企业应用中的各种业务管理的功能所需的web交互差不多就是这样的。

C这里需要控制所有这些form和submission(action)的flow。这里要解决无状态的问题。

所以比较理想化的分析就是这样:

用户请求一个特定任务,则C先找到该任务的flow,然后找到flow中与当前状态所对应的form(view)。view内会通过某种机制(通常就是URI)绑定许多数据实例。注意这里不应由C直接去填充数据给UI组件,应该由view声明其所需的数据源,并由view自己把从数据源得到的数据实例和view中的UI组件绑定起来。这样才是UI归UI,app归app。这里是松耦合的,M和C都不知道V中的UI细节。

其他部分与现在的web MVC基本相同。比如当V提交了数据到C时(与现在已有的方式一样,这里的action分派由submission指定,但C也可以进一步分派),C执行app logic,处理传入的数据,如调用service,更新model,选择下一个view等等。

在这样的模型里,绑定是发生在UI组件和model的instance之间的,通过基于某种表达式语言灵活的绑定(你也可以坚持只用id绑定,但是显然这是作茧自缚),我们就解耦了ui和model。而且UI可以是抽象UI,即我们可以进一步解耦UI模型和UI的具体形式。这里需要强调一点,解耦程度有多高,关键不在于你用id绑定还是用el(因为model你是可以自行规约简化的),而是取决于UI组件的能力。UI组件对于model的假设和限制就越小,与model的耦合程度自然就越低。这就是我为什么说V越强大MVC越强大。
89 楼 TomHornson 2008-03-28  
IoVC,会不会说只能用在极端简单的场景中(甚至还囿于JSF框架)。
从大的方面来说:
1、BO、DTO的View是多样的,HTMLComposer,XML+XSTL,Template等技术的应用,就说明实际问题不是你一个那么简单的IoVC就能解决的。
2、AJAX技术在当前的B/S应用中大量使用,它只能首先获取Model,然后在Browser展示。
从小的方面来说:
1、Bean绑定的功能会不会太弱?
public class Cart{ 
  private int flag;
  private Collection pods;
}

if(1 == flag){
  view1
}else if(2 == flag){
  view2
}等带有逻辑的,
或者如pods这种集合,怎么处理?

感觉,这种Bean中注入View的做法,基本不可行,因为稍微复杂的应用,后端数据和View之间都有一个鸿沟需要去填。

相关推荐

    OperaMasks快速进阶

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

    机械原理课程设计 破碎机.doc

    机械原理课程设计 破碎机.doc

    电子设计论文施密特触发器电子设计论文施密特触发器

    电子设计论文施密特触发器电子设计论文施密特触发器

    电子设计论文往返式流动灯电子设计论文往返式流动灯

    电子设计论文往返式流动灯电子设计论文往返式流动灯

    基于深度学习来实现序列到序列.zip

    深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。

    美国扩大电动汽车充电基础设施政策(英文).pdf

    政策背景与动机: 签署法案:2021年11月15日,拜登总统签署了《基础设施投资和就业法案》(IIJA),旨在通过多项措施推动美国电动汽车充电基础设施的扩张。 市场增长:随着电动汽车市场的快速增长,对充电基础设施的需求也日益增加,政府政策成为推动这一发展的关键力量。 电动汽车充电基础: 充电技术:电动汽车充电技术通常分为三级,各级充电速度和功率不同,满足不同场景下的充电需求。 充电站类型:包括公共、私人及工作场所充电站,各自具有不同的访问限制和使用特点。 市场趋势与现状: 市场增长:EV市场增长依赖技术进步、成本降低及充电便利性的提高。 充电站数量:截至2022年10月,美国公共和私人充电站总数超过50,000个,其中93%为公共充电站。 区域差异:充电站分布存在地区差异,部分低收入社区充电基础设施不足。 政策与项目: NEVI公式计划:通过IIJA设立的国家电动汽车基础设施(NEVI)公式计划,为各州提供资金以建设EV充电站。 税收抵免:扩展了替代燃料汽车加油站的税收抵免政策,包括EV充电站,以激励投资者。 联合办公室:DOT和DOE成立联合办公室,负责NEVI计划的实施和监管,确保

    电子设计论文照明过暗提醒电路电子设计论文照明过暗提醒电路

    电子设计论文照明过暗提醒电路电子设计论文照明过暗提醒电路

    前端,HTML+CSS的综合案例,网页开发

    我选用的软件是:Visual Studio CODE,这个软件在前端开发中十分常用,且提供了很大的便利。 当然也可以用记事本开发,记得把后缀名改成.html 还有我的CSS使用的是内部样式表。 写在head标签下。用到的标签有  <h1></h1>    <img src="lyf.jpg" class="god">     <p>    </p> 就是这三个标签,构成了HTML的主体架构。 而CSS则是设置了以下形式。 font-size: 16px;             line-height: 32px;             font-family: "Microsoft Yahei";             text-align: left;             text-indent:2em;          text-decoration: none;             color: #888888         width:66px

    MFC MAPI 源码和可执行文件

    大名鼎鼎的MFC MAPI 源码和可执行文件,是开发OUTLOOK插件的好帮手。

    机械原理课程设计插床机构机械设计.doc

    机械原理课程设计插床机构机械设计.doc

    基于深度学习的音频分类 前端App.zip

    深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。

    基于BERT模型的深度学习中文文本分类实现,包含大约20000条新闻的训练和测试集,包装有简单HTTP接口可供调用。.zip

    深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。

    《化工设备机械基础》课程设计 IB储罐设计.doc.doc

    《化工设备机械基础》课程设计 IB储罐设计.doc.doc

    机械原理课程设计网球自动捡球机.doc

    机械原理课程设计网球自动捡球机.doc

    EKFUKFCKF录屏.mp4

    EKFUKFCKF录屏.mp4

    仿新浪读书小程序源码学习

    仿新浪读书小程序源码学习

    基于科大讯飞AI营销算法比赛实现CTR深度学习方法.zip

    深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。

Global site tag (gtag.js) - Google Analytics