`
apusiczhang
  • 浏览: 17398 次
  • 性别: 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之间都有一个鸿沟需要去填。

相关推荐

    AOM介绍-Web开发敏捷之道.

    OM提供了一种简化的编程模型,通过使用如`w:textField`、`w:button`、`w:dataGrid`等组件标签,以及`@Bind`、`@ValidateLength`、`@DataModel`、`@Action`等注解,开发者可以轻松地实现数据绑定、校验、动作处理等...

    OperaMasks快速进阶

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

    直播项目微信小程序源码(类似于微信视频通话).zip

    《直播项目微信小程序源码简介》 本资源是一份极具学习价值的直播项目微信小程序源码,类似于微信视频通话功能。它为开发者提供了一个完整的直播项目框架和实现逻辑,可用于深入研究直播技术在小程序中的应用。 该源码涵盖了直播项目的核心功能模块,包括视频采集、推流、播放等关键部分。通过对其代码结构的研究,开发者可以了解到如何利用微信小程序的相关接口和功能来实现流畅、稳定的直播体验。例如,在视频采集方面,源码展示了如何在小程序中调用设备摄像头,并进行实时视频数据的处理;在推流环节,详细阐述了如何将采集到的视频数据推送到服务器,以供其他用户观看;而在播放部分,则清晰地展示了如何在小程序界面上实现视频的流畅播放和控制。 这份源码不仅有助于开发者掌握直播技术在小程序中的实际应用,还能为进一步开发和优化直播类小程序提供宝贵的参考和借鉴,是一份不可多得的学习资源。

    详细阐述了中国智慧医疗建设的发展历程、现状、挑战及未来趋势 以下是文章的主要内容总结:

    内容概要:本文详细探讨了智慧医疗建设的历程、现状、挑战及未来发展趋势。智慧医疗建设经历了信息化、数字化和数智化三个阶段,政策、需求和技术是其发展的三大推动力。文章指出,当前智慧医疗已从数据收集与治理阶段迈向数据价值应用阶段,特别是在高质量数据库建设、云计算、人工智能等技术的推动下,实现了临床科研、药物研发、真实世界研究及数字营销等多个场景的商业化落地。此外,文中还分析了医疗信息化系统同质化、数据孤岛、互联互通等痛点,并提出了云化转型、新产品、新技术和新服务作为突破方向。最后,通过奈特瑞、医渡科技、东软集团三个企业案例,展示了不同企业在智慧医疗领域的创新实践。 适合人群:医疗信息化从业者、医疗行业研究人员、医疗机构管理者、医疗科技企业相关人员、政策制定者及对智慧医疗感兴趣的投资者。 使用场景及目标:①了解智慧医疗建设的阶段性特征和发展趋势;②掌握医疗信息化建设中的关键技术和应用场景;③探讨解决医疗信息化系统同质化、数据孤岛等问题的策略;④学习企业如何通过新产品、新技术和新服务实现突破,推动智慧医疗发展。 其他说明:本文通过对智慧医疗建设的深入剖析,强调了政策导向、技术创新和市场需求的重要性,为企业和政策制定者提供了宝贵的参考。同时,文章也揭示了未来智慧医疗发展的广阔前景,特别是在数据资产化和数智化应用方面的巨大潜力。阅读时应注意结合政策背景和技术发展趋势,关注行业动态和企业创新实践。

    电机设计领域中8级48槽永磁同步电机振动噪声分析的Motor CAD应用

    内容概要:本文详细介绍了利用Motor CAD软件对8级48槽永磁同步电机进行振动噪声分析的方法和步骤。主要内容涵盖前期准备工作,如软件环境搭建和基本原理的理解;建立电机模型的具体细节,包括定子和转子部分的参数设置;振动噪声分析的相关设置,特别是电磁力波的计算方法及其重要参数的设定;以及最终分析结果的解读,包括振动模态图和噪声频谱分析结果的应用。通过这些步骤,可以识别出导致较大振动和噪声的问题所在,并提出针对性的优化措施,如调整槽配合、优化永磁体形状等,以改善电机的整体性能。 适合人群:从事电机设计与优化的专业人士,尤其是对永磁同步电机振动噪声分析感兴趣的工程师和技术人员。 使用场景及目标:适用于希望深入了解和掌握Motor CAD软件在电机振动噪声分析方面应用的技术人员。目标是在实际工作中能够运用所学知识,提高电机的设计质量和性能,减少不必要的振动和噪声。 其他说明:文中提供了大量具体的代码片段和操作指南,帮助读者更好地理解和实践。同时强调了电磁-机械-声学耦合的重要性,指出结构设计对于降噪的关键作用。

    【计算机教育】计算机专业课后习题高效学习策略:构建知识体系与应对考试重点

    内容概要:本文是一篇面向计算机类专业学生的课后习题学习指南,强调课后习题对于构建专业知识体系的重要性。文章指出,做题不仅是为了完成任务或应付考试,更重要的是理解知识点背后的原理。文中详细介绍了不同课程类型的习题应采用的不同方法,如程序设计类需多动手调试,数据结构与算法类要手动画图并多敲代码等。同时提醒学生注意考试重点往往隐藏在课后题中,并提倡通过迭代学习巩固知识,避免常见错误。 适合人群:计算机类专业的学生,特别是那些在课后习题练习中遇到困难或希望提高学习效率的人群。 使用场景及目标:①帮助学生掌握正确的课后习题练习方法;②指导学生根据课程特点选择合适的做题策略;③提醒学生关注课后题中的潜在考试重点;④通过迭代学习的方式强化理解和记忆。 阅读建议:本文提供了实用的学习技巧和建议,读者应在实际做题过程中尝试运用这些方法,不断调整和优化自己的学习方式,以达到更好的学习效果。

    四旋翼无人机轨迹跟踪:PID与自适应滑模控制的Matlab仿真研究

    内容概要:本文详细探讨了四旋翼无人机(UAV)的轨迹跟踪控制技术,重点介绍了两种主流控制方法:PID控制和自适应滑模控制。首先,文章阐述了PID控制的基本原理及其在Simulink中的具体实现步骤,展示了如何通过调节PID参数实现稳定的轨迹跟踪,并提供了详细的Matlab代码示例。接着,文章深入讲解了自适应滑模控制的工作机制,强调了其对系统不确定性的强鲁棒性特点,并给出了相应的Matlab实现代码。此外,文中通过多种图表形式展示了不同控制方法下的仿真结果,直观比较了它们的优缺点。最后,作者总结指出,PID控制适合于系统模型较为确定的情况,而自适应滑模控制则更适合应对复杂的外部环境和不确定性因素。 适合人群:对无人机控制系统感兴趣的科研人员、工程技术人员及高校相关专业学生。 使用场景及目标:①帮助读者理解并掌握PID和自适应滑模控制的基本原理;②提供具体的Matlab/Simulink实现案例,便于读者进行实际操作练习;③通过对两种控制方法的对比分析,指导读者选择合适的控制策略应用于实际项目中。 其他说明:文章不仅提供了详尽的技术细节,还包括了许多实用的小技巧和经验分享,有助于提高读者的实际动手能力和解决问题的能力。

    电力电子领域LLC谐振变换器PFM+PSM混合控制仿真及其应用

    内容概要:本文详细探讨了LLC谐振变换器中变频移相(PFM+PSM)混合控制的仿真研究与实现。首先介绍了这种方法可以拓宽输入电压范围,确保MOS管的零电压开通(ZVS)和二极管的零电流关断(ZCS),从而降低开关损耗并提高变换器效率。接着展示了在Matlab/Simulink和Plecs环境下的具体实现步骤,包括关键参数设置、模式切换逻辑以及波形展示。文中还强调了参数整定的重要性,如谐振腔Q值的影响,并给出了具体的解决方案。此外,讨论了仿真过程中需要注意的问题,如仿真步长的选择和软开关条件的检测。 适合人群:从事电力电子设计的研究人员和技术工程师。 使用场景及目标:适用于需要设计高效、稳定电力转换系统的场合,特别是在输入电压范围较广的应用中,如光伏逆变器。目标是通过合理的控制策略实现更高的效率和平滑的工作状态。 阅读建议:读者应重点关注PFM和PSM模式的具体实现细节,尤其是两者之间的平滑切换逻辑,同时也要注意仿真工具的选择和参数调整技巧。

    【移动应用开发】VIP学习资源整合:涵盖Android、iOS、React Native及Flutter的开发工具、资源与社区

    内容概要:本文汇总了移动应用开发领域的VIP学习资源,涵盖从基础入门到进阶提高的全方位内容。基础资源方面,推荐了针对Android、iOS、React Native的多本经典书籍及Udemy、Coursera、edX等平台上的在线课程和YouTube视频教程,帮助初学者掌握UI设计、数据存储、前后端交互等基本技能。进阶资源则聚焦于高效编程、性能优化、架构设计等深层次主题,同样提供了书籍、在线课程和视频教程。对于跨平台开发,重点介绍了React Native和Flutter的相关学习资料。此外,还列举了Android Studio、Xcode等常用开发工具及其配套调试工具,以及Flutter Gallery、React Native Showcase等开源项目作为实践参考。最后,提及了Stack Overflow、Reddit - AndroidDev等社区论坛,为开发者提供交流平台。 适合人群:对移动应用开发感兴趣的初学者、有一定经验的研发人员及希望深入了解跨平台开发的开发者。 使用场景及目标:①初学者可以通过书籍、在线课程和视频教程系统学习移动应用开发的基础知识;②进阶者可利用进阶资源深入研究特定技术领域,如性能优化、架构设计等;③跨平台开发者可以借助React Native和Flutter的学习资料实现多平台应用开发;④使用推荐的开发工具和调试工具提高开发效率,解决实际问题;⑤通过开源项目和社区论坛获取实践经验和技术支持。 阅读建议:根据个人技术水平选择合适的资源进行学习,注重理论与实践相结合,积极参与社区交流,不断提升自己的移动应用开发能力。

    【深度学习框架】Caffe与Python接口的使用指南:从安装到模型部署的全流程解析

    内容概要:本文详细介绍了深度学习框架Caffe及其Python接口的使用方法。首先概述了Caffe的特点,如速度快、支持多种神经网络类型(CNN、RNN、LSTM),并提供预训练模型库。接着阐述了Caffe的安装步骤,包括系统要求、依赖库安装、源码编译及Python接口的配置。随后,文章通过多个示例展示了如何使用Python接口加载模型、预处理数据、执行前向传播和进行预测。此外,还介绍了模型训练流程,包括配置训练参数、使用Python接口训练模型、动态调整超参数等。最后,讨论了模型部署与应用,涵盖模型定义、训练、转换、加载、预测及性能评估等方面,并提供了常见问题的解决方案。; 适合人群:对深度学习有一定了解并希望使用Caffe框架进行模型开发的研究人员和工程师。; 使用场景及目标:①掌握Caffe框架的安装配置;②学会使用Python接口加载模型、预处理数据、执行前向传播;③理解模型训练流程,包括配置训练参数和动态调整超参数;④熟悉模型部署与应用,如模型定义、训练、转换、加载、预测及性能评估。; 阅读建议:由于Caffe的Python接口涉及较多的技术细节,建议读者在阅读时结合实际操作练习,逐步掌握每个步骤的具体实现方法。同时,可以参考官方文档和社区资源,加深对Caffe的理解和应用。

    基于西门子200PLC与组态王6.53的锅炉内胆温度控制系统设计与实现

    内容概要:本文详细介绍了使用西门子200PLC和组态王6.53实现锅炉内胆温度控制系统的全过程。首先,通过PLC采集温度数据并进行控制逻辑编程,确保温度保持在设定范围内。其次,组态王用于创建可视化界面,使用户能够实时监控和调整温度参数。文中还展示了具体的梯形图编程实例,如温度采集、控制逻辑、PID调节等,并讨论了常见的调试技巧和注意事项。此外,提供了运行效果视频,直观展示了系统的实际性能。 适合人群:从事工业自动化领域的工程师和技术人员,特别是熟悉PLC编程和HMI软件使用的专业人士。 使用场景及目标:适用于需要精确控制温度的工业应用场景,如化工、制药等行业。主要目标是提高温度控制的精度和稳定性,减少能源消耗,提升生产效率。 其他说明:文中提到的一些具体技术和参数(如PID参数、定时器设置等)可以根据实际情况进行调整优化。同时,强调了硬件配置和接地处理的重要性,以确保系统的可靠性和抗干扰能力。

    微纳光学中COMSOL仿真:铌酸锂和频转换与磁偶极子准BIC反射相位计算

    内容概要:本文详细介绍了COMSOL在微纳光学领域的应用,重点探讨了两个方面:一是基于X切型绝缘体上铌酸锂薄膜(LNOI)进行和频产生(SFG)转化效率的仿真,二是磁偶极子贡献下的准BIC斜入射反射相位计算。文中不仅解释了相关理论背景,还展示了具体的参数设置方法和仿真步骤,如自定义入射基频波长、光强、偏振方向等,并通过实例演示了如何在COMSOL中实现这些仿真的具体操作。此外,文章还讨论了不同参数对SFG转化效率和反射相位的影响,强调了材料性质、入射角度、光强等因素的关键作用。 适合人群:从事微纳光学研究的科研人员和技术开发者,尤其是那些希望深入了解COMSOL仿真技术及其在非线性光学和准BIC现象中应用的人群。 使用场景及目标:①帮助研究人员更好地理解和优化LNOI材料中的SFG转化效率;②辅助设计高性能的微纳光学器件,如高Q值谐振腔、高效反射镜或滤波器等;③为探索新的光学现象提供理论支持和技术手段。 其他说明:文章提供了详细的仿真代码示例和避坑指南,便于读者快速上手并避免常见错误。同时,作者鼓励读者通过参数化扫描等方式挖掘更多潜在的新物理现象。

    2025 STM32单片机YT2号-任务2-键控LED【嵌入式系统】基于STM32单片机的按键控制LED设计:洋桃2号开发板任务实现与代码解析

    内容概要:本文档详细介绍了使用STM32CubeIDE开发环境在洋桃2号开发板上实现按键控制LED的功能。首先,指导用户解压并打开任务2的工程文件,然后进行GPIO参数配置,包括4个按键和4个LED的设置。接下来,通过建立BSP文件夹及其内部的C和H文件来组织代码结构,提供了延迟、LED控制以及按键检测的具体代码实现。每个LED都有独立的控制函数,可以单独点亮或熄灭,并支持整体操作。按键检测函数能够识别按键按下事件并返回相应的状态值,同时处理了按键抖动的问题。最后,文档还简述了编译、运行和调试代码的基本步骤。 适合人群:具有初步单片机编程基础的学生或工程师,特别是对STM32系列微控制器有一定了解的人士。 使用场景及目标:①学习STM32CubeIDE开发环境的使用方法;②掌握GPIO端口配置及基本外设控制;③理解按键去抖动机制和LED驱动程序的设计与实现;④熟悉嵌入式系统的开发流程,包括代码编写、编译、下载和调试。 阅读建议:此文档适用于实际动手操作,读者应按照文档步骤逐步进行实验,同时参考提供的代码示例,以便更好地理解和掌握相关知识点。在遇到问题时,可以通过查阅官方文档或在线资源来解决问题。

    基于uni-app开发的菜谱小程序新版源码.zip

    《基于 uni-app 开发的菜谱小程序新版源码》简介 这是一份极具实用价值的学习资源——基于 uni-app 开发的菜谱小程序新版源码。uni-app 凭借其多端适配的强大特性,一次开发就能在多个平台运行,极大地提升了开发效率与应用覆盖范围。 此菜谱小程序源码功能丰富。它拥有精美且简洁直观的界面设计,方便用户快速上手操作。在内容呈现上,涵盖了海量的菜谱资源,无论是家常小菜、地方特色菜肴,还是异国料理,都能在其中找到详细的做法教程,步骤清晰,图文并茂,甚至部分还搭配了视频讲解,让烹饪新手也能轻松学会。 对于开发者而言,这份源码是学习 uni-app 开发的绝佳范例。可以深入研究其代码架构、页面布局、数据交互以及各种功能的实现逻辑,从中汲取经验,提升自己在跨平台移动应用开发方面的能力,更好地理解 uni-app 框架的优势与应用场景,为后续的开发项目奠定坚实的基础,助力开发出更多优质且高效的应用程序。

    电动汽车永磁同步电机设计:基于Prius 2004的Excel计算、Maxwell仿真与MotorCAD温升分析

    内容概要:本文深入探讨了丰田Prius 2004永磁同步电机的设计过程,涵盖了从Excel设计程序到Maxwell参数化仿真的各个环节。首先介绍了利用Excel进行初步设计计算的方法,通过设定关键参数如功率、转矩等,计算出电机的体积、叠厚、匝数等重要设计指标。接着讨论了Maxwell参数化仿真模型的应用,展示了如何通过调整参数并运行仿真,直观地观察磁场分布和转矩波动等结果。此外,文章还提到了橡树岭实验室提供的拆解和实测数据,强调了这些一手资料对于验证设计和仿真的重要性。最后,介绍了MotorCAD模型在温升仿真分析中的应用,解释了如何设置热学参数并预测温度分布,确保电机的稳定性和可靠性。 适合人群:从事电动汽车电机设计的研究人员和技术人员,以及对电机设计感兴趣的工程专业学生。 使用场景及目标:适用于需要深入了解永磁同步电机设计原理和方法的人群,旨在提供从理论到实践的全面指导,帮助读者掌握电机设计的关键技术和工具。 其他说明:文章不仅提供了详细的理论讲解,还附带了大量的实例和代码片段,便于读者理解和实践。同时,文中提到的多种工具和方法可以相互结合,形成一套完整的电机设计流程。

    (源码)基于C语言的TCPIP网络编程.zip

    # 基于C语言的TCPIP网络编程 ## 项目简介 本项目是一个基于C语言的TCPIP网络编程学习项目,涵盖了从基础的套接字编程到高级的多线程服务器设计。项目内容包括TCP和UDP协议的使用、多线程编程、IO复用、信号量和互斥量的应用等。通过这些内容的学习和实践,开发者可以深入理解网络编程的核心概念和技术。 ## 项目的主要特性和功能 1. TCPIP编程 创建TCP服务器和客户端,实现基本的网络通信。 使用套接字进行数据的发送和接收。 处理TCP连接的建立、数据传输和断开。 2. 多线程编程 使用pthread库创建和管理线程。 在多线程环境中处理共享资源,如全局变量和文件描述符。 通过信号量和互斥量实现线程同步,确保对共享资源的正确访问。 3. IO复用 使用select()和epoll实现IO复用,提高服务器的并发处理能力。 处理多个客户端的并发连接和数据传输。

    财务分析的哈佛框架.ppt

    财务分析的哈佛框架

    电磁学领域中Comsol/CST模拟狄拉克半金属BDS超材料的Matlab脚本与模型应用

    内容概要:本文详细介绍了使用Comsol和CST软件模拟狄拉克半金属BDS超材料的方法和技术细节。文中不仅解释了这两种软件在处理电磁、热等多物理场耦合方面的优势,还提供了具体的Matlab脚本用于超材料的数据预处理和后处理,如计算波数、模拟散射图案等。此外,文章分享了多个CST模型实例,包括简单单元结构模型和周期阵列模型,展示了如何通过调整材料参数和结构设计来优化超材料的电磁响应特性。同时,针对BDS超材料在太赫兹波段的独特电磁响应,提出了若干实用的设计和仿真技巧,如交叉偏振设计、时域求解器设置以及边缘场校正等。 适合人群:从事电磁学、材料科学领域的研究人员和技术人员,尤其是对超材料设计感兴趣的科学家。 使用场景及目标:适用于需要深入理解和掌握超材料电磁响应特性的科研项目,旨在提高超材料设计效率和精度,探索新的电磁调控方法。 其他说明:文章提供的Matlab脚本和CST模型能够帮助读者更好地理解和应用狄拉克半金属BDS超材料的相关理论和技术,促进学术交流和技术进步。

Global site tag (gtag.js) - Google Analytics