??xml version="1.0" encoding="utf-8" standalone="yes"?>
传统的服务器端MVC架构设计Q也是Model2Q,存在着一个基本的假设是Web应用的工作流是由一pd的页面切换构成的。这U架构中的一个ViewQ从语义上来讲只能代表一个完整的HTML面。整个Web应用的表现层Q被划分成ؓ(f)非常多的面的组合?
而Ajax开发者眼里,W(xu)eb应用的工作流q不是这h成的。Ajax开发者看待Web应用的角度与传统开发者相比差别非常大。在一个Ajax应用中,只有相对很少的页面。每个页面,包括面引用CSS样式、JS脚本Q都是一个更型的Ajax应用。甚至一些功能简单的Ajax应用Q本w仅仅由一个单一的页面构成。例如一个简单的RSS阅读器,q有IBMW记本上那个获得天气预报的桌面?br />按照Ajax in ActionQAjax应用可以分成3U类型:(x)
自从1999qM$推出IE5.0支持XMLHTTPQ可以不h面以异步方式从服务器获取数据之后,W(xu)eb开发的领域埋下了一颗定时炸弹(6q以后,一个新词Ajax的出现引爆了q颗炸弹Q。Model2最初的设计应该发生在这件大事(现在应该承认QM$做了一件天大的好事Q发生之前,其设计师不可能想到异步请求的价倹{按照Model2的设计思想直接产生了Struts。但是后来的WebWork在最初设计阶D仍然与q个技术失之交臂,q是相当可惜的一件事情。WebWork其实最初设计的时候就可以走的更远Q但是他们只惌StrutsQ做一个更好的Model2 MVC开发框架。现在他们再惌上这班列车已l有Ҏ(gu)了。如果基的服务器端MVC架构的h(hun)值是可疑的,那么其他围绕q个架构所开发的基础架构的h(hun)g同样是可疑的?
所以在现在q个时刻Q重新正本清源地思考Model2最初的设计Q它带来的Web开发的巨大q步Q以?qing)它所存在的不I是一个非常现实的问题?/font>
上面的六U异常对象都l承?strong>Error对象。他们都支持以下两种构造方?
手工抛出异常的方法如下:(x)
如要判断异常信息的类型,可在catch中进行判断:(x)
Errorh下面一些主要属性:(x)
Z么我说Struts/WebWork?x)受到Ajax的威胁呢Q有的h可能觉得大家相安无事不是很好Q你是不是有经病故意挑起h民内部矛盾?问题是他们之间确实存在着一些深层的内在矛盾和冲H,q些矛盾才是目前Struts?WebWork都只能在非常有限的程度上支持Ajax的原因。所以,问题是架构性的Qƈ不是型的修补或者更好的~程技巧可以彻底解决的?
服务器返回给Ajax应用?U类型的|络量Q不UCؓ(f)数据是与上面W?UAjax应用相区别)(j)QQ何一U都不能被简单地视作传统MVC架构中的ViewQ因Z们各自所代表的语义与传统MVC架构中的View的语义是完全不同的。所以可以看出,除了初次交付l浏览器一个完整的Ajax应用之外Q传l的MVC架构对于Ajax应用的支持是非常有限的。其实ؓ(f)了给客户端提供上?cȝl流量,一个Servlet已经_了。DWR、JSON-RPC、Buffalo在服务器端也是由Servlet实现的,不要求服务器端一定要安装某种MVC框架?br />上面3cd用,前面的两c,客户端JS代码比较单,表现逻辑仅有一部分位于客户端,大部分仍然位于服务器端,因此传统的服务器端MVC架构仍然是非常有价值的。但是大家注意第3cAjax应用Q实际上它已l将l大部分甚至可以全部的表现逻辑都{Ud客户端来执行Q这个时候服务器端传l的Web表现层实际上被架IZQ皮之不存,毛将焉附Q)(j)。而对于Ajax应用来说Q虽然近期可能还是以W?cAjax应用ZQ例如,所谓的AHAH技术)(j)Q但是最有生命力和发展前景的q是W?cAjax应用?
]]>
]]>
try
{
foo.bar();
}
catch
(e)
{
alert(e.name
+
"
:
"
+
e.message);
}
目前我们可能得到的系l异怸要包含以?U?
new
Error();
new
Error(
"
异常信息
"
);
try
{
throw
new
Error(
"
Whoops!
"
);
}
catch
(e)
{
alert(e.name
+
"
:
"
+
e.message);
}
try
{
foo.bar();
}
catch
(e)
{
if
(e
instanceof
EvalError)
{
alert(e.name
+
"
:
"
+
e.message);
}
else
if
(e
instanceof
RangeError)
{
alert(e.name
+
"
:
"
+
e.message);
}
//
etc
}
因此Z更好的了解错误信息我们可以将catch部分改ؓ(f)如下形式Q?
try
{
foo.bar();
}
catch
(e)
{
if
(browserType
!=
BROWSER_IE)
{
alert(
"
name:
"
+
e.name
+
"
\nmessage:
"
+
e.message
+
"
\nlineNumber:
"
+
e.lineNumber
+
"
\nfileName:
"
+
e.fileName
+
"
\nstack:
"
+
e.stack);
}
else
{
alert(
"
name:
"
+
e.name
+
"
\nerrorNumber:
"
+
(e.number
&
0xFFFF
)
+
"
\nmessage:
"
+
e.message
"
);
}
}
JavaScript中的throw命o(h)事实上可以抛ZQ何对象,q且我们可以在catch接受到此对象。例如:(x)
try
{
throw
new
Date();
//
抛出当前旉对象
}
catch
(e)
{
alert(e.toLocaleString());
//
使用本地格式昄当前旉
}
]]>
随着Ajax的升温,开发h员逐渐对Web应用中的各种UI控g和开发框架开始有了越来越厚的兴。目前所知的q方面的控g集或开发框架可以说是ƈ不鲜见。笔者将q些产品大致分ؓ(f)两个大类Q离散控仉型和数据模型驱动型。这两个词大家应该很陌生Q因Z们都是鄙造的?br />
L控g集型 Q?此类产品以提供一pd相对独立的界面控件ؓ(f)主要目的。控件的cd比较全面Q例如搭建Web应用常见的各UGrid、Tree、Menu、ToolBar、Window{。不q此cM品一般不?x)过多的考虑界面中的数据和操作逻辑的封装,臛_只会(x)提供相对单的静态数据绑?。我认ؓ(f)此类产品的主要出发点是改善Web应用的界面表现能力,同时借助自带的SDK提供一U更加规范的开发模式?br />目前我所知的大部分品似乎都属于q一cd。例? backbase、qooxdoo、NetAdventage、bindows{?br />Backbase实例中心:
http://www.backbase.com/demos/explorer
数据模型驱动?/strong> Q?此类产品除了要提供一l比较好用的UI控g集之外,更会(x)提供对界面中数据模型的管理功能。其UI控g以数据敏感控件ؓ(f)丅R数据敏感控件可以通过于数据模型的l定来实现对表现层中数据的展C和控制。这U数据绑定可成ؓ(f)动态数据绑?。可以说q一cM品的主要出发炚w改善Web应用的界面表现能力外Q也非常注重提供一U快速开发的模式?br />好的数据模型驱动型的开发框架应该首先包含离散控仉中的各种功能Q它事实上是一U相对于单纯的UI控g集而言更高层次的抽象?br />
q种模式其实在以前CS下非常常见,例如VB、Delphi{RAD开发工h交数据库应用开发模式都属于q种cd。不q到了BS下h们似乎都忘记q种开发模式。可能是因ؓ(f)不够见多识广Q目前笔者所知的此类产品只有dorado?br />dorado的示例中心:(x)
http://sample.bstek.com
对于上面提到的两U数据绑定方式的解释如下Q?br />
静态数据绑?/strong> ?是指在控件可以根据指z他的数据?往往是XML数据源或单的数组)自动的提取ƈ展示其中的数据。这U提取过E是d完成的,当提取过E结束后控g无法l箋感知数据源中数据的变化。这事实上是从控件到数据源的拉模?Pull Mode)?br />
动态数据绑?/strong> ?是指控件以观察者的角色注册到数据源(往往是经q封装的U有对象)中。数据源成ؓ(f)被观察者。当数据源中的数据或状态发生改变时?x)主动通知所有观察者(即绑定的控gQ,然后再由控g自动提取数据完成展现的更新。这样一旦绑定徏立以后控件就可以实时的体现数据源中的最新变化。如果用户利用这些控件对数据或状态做了改变,那么q种改变自然也会(x)通过数据源再实时的通知l所有其它相关的控g。这事实上是从数据源到控件的推模?Push Mode)?br />
回到关于L控g集型和数据模型驱动型的讨论。这两种开发框枉有这自己的适用面。笔者认为离散控仉型的开发框架更加适合与一些像论坛q样更加注重展现的应用。而对于那些具有明显数据库应用Ҏ(gu)的的Web应用(例如MIScd?Q则数据模型驱动型的开发框架更能发挥它的优ѝ?br />得出以上l论的原因是我认为数据模型驱动型的开发框架能够开发h员将更多的精力投入到界面所需要实现的更能当中Q至在制作面的前期阶D不必太多的x界面的表现Ş式。同时如果能够将更多的界面操作逻辑装到数据模型对象中Q就可以保证在后期当最l用h出界面的修改要求Ӟ开发h员可以用更小的代h完成对界面的重构?br />
让我们来具体分析两个场景:
场景1Q一个用惯了CS应用的用戯求开发一个界面来l护公司目前拥有的所有书c。ؓ(f)了方便的完成Ҏ(gu)有书c的CRUD操作Q用户希望以一个Grid控g来完成所有这些操作,同时用户希望能够在界面批量的完成一pdC、U、D操作之后一ơ性的Ҏ(gu)据进行保存。每本书c都有一个由pȝ自动分配的编码作Z键,因此用户不需要看Cc的~码?br />分析Q如果我们现在只有一个离散的Grid控g。要完成上述功能我们q需要做以下一些工?
在基于离散控件的~程方式中,我们需要知道n份证、出生日期、性别q三个编辑框的idQƈ针对他们q行~程。其代码形式可能如下:
在基于数据模型驱动型框架的编E方式中Q我们ƈ不需要关注界面上摆放了什么控Ӟ只需要知道关注如何操作数据模型对象。其代码形式可能如下:
可见在这U开发模式中我们的代码几乎完全针Ҏ(gu)据模型展开Q当我们为dmUser中的brithday和sex赋值后Q相应的数据敏感控g?x)立刻自动显C出q些的数据。这L(fng)~程模式可以让代码有高度的一致性,当我们制作复杂的用户界面Ӟ可以不需要记住诸多的控gid?br />q一步假设。如果用h一天觉得这L(fng)界面q不方便对多W数据进行方便的l护Q而要求对界面q行如下调整。在删除原先的表单,利用一个Grid控g来对用户信息q行l护?br />
如果我们的编E方式是ZL控g的,那么我们不可避免的要对先前编写那D代码做一些调整了。我需要将那段代码UL到表格当中?br />但是如果我们的编E方式是Z数据模型驱动型框架的Q那么我们要做的只是界面上的表单删掉,然后在放|一个与现有数据模型l定的Grid控g。至于那D代码,它完全不需要做M变动?br />
lg可见Q在MIScWeb应用的表现层开发方面。数据模型驱动型的开发框架可以ؓ(f)开发h员带来更多的实惠。不知道随着旉的推U这一cȝ开发框架会(x)不会(x)丰富hQ?br />
参考文?/span>
: [原创] Web表现层的Client端设计模式探?/a>
q里提到的表现层应当是指包含Server端的展现相关的逻辑以及(qing)览器中的逻辑。在传统的开发方式中表现层逻辑往往只涉?qing)到Server端,而到了Client端已完全变成了HTML+CSS或XML+XSLT毫无设计模式可言。笔者认为随着技术的发展和AJAX的推动,我们有必要将一部分表现层逻辑推向览器已q一步增强界面的交互能力?
或许目前大家设计的WEB面q很需要考虑对展现数据的理。但是一旦有一天我们拥有了一套好用的UIlg库,那时我们设计的用户交互界面的复杂度也׃(x)H破目前我们?fn)惯认?f)的上限。想像一个稍微有点复杂的场景Q如果我们拥有了一个像Excel一L(fng)可以对Q意单元进行实时编辑的GridlgQ用户可以对其中的数据做L的增删改操作Q那么我们就必须要考虑一下如何将用户所填入的数据以合理有效的方式提交回Server端了?br />
CS中的展现数据模型对象
不过真的要来设计一U在表现层中的数据模型,q真是有点千头万~、无从下手。所以在具体考虑如何理q些数据之前Q我们先来看一看在传统的CS应用中数据是如何q行理的,有没有什么可以借鉴的东西?不约而同的,在这些开发模式中都能扑ֈ一U专用的数据模型对象Q在VB中它叫ADO.RecordSet、在Delphi中它叫TDataSet、在PB中它叫DataWindow。它们都有一些共同的特点Q?
1. 表驱动的l构, h当前记录的概c(din)?br />表驱动的设计模式是由关系型数据库自然衍生q来的设计方式,q种设计非常有利于用户对数据的浏览和~辑Q也W合我们对同l构扚w数据q行览和编辑的一般理解和?fn)惯?
2. 控g可直接与数据模型q行l定?/span>