用户处理组件接口设计
用户处理组件的接口要暴露以下类型的功能性,如图2.5所示。
l 用户处理的“行为”(1)。有一些行为接口,这些接口典型的用法是触发用户处理状态的改变。行为被实现在用户处理组件的方法内,如在前面的代码中的ShowOrder, EnterPaymentDetail, PlaceOrder,和Finish方法。在这些行为方法中用于封装对业务组件的调用(6)。
l 状态访问方法(2)。可以访问明确的业务状态和不明确的业务状态,用户处理通过使用良好的get和set的属性方法,或者通过暴露一批用户处理的业务实体(5)。例如,前面讨论的代码例子中,用户处理状态通过公开的DataSet属性获取。
l 状态改变事件(3)。当用户处理的业务相关状态或者不明确的业务状态改变时,这些事件被触发。有时还需要实现自身的改变通知。在另一种情况下,可以通过已存在的固有的机制存储数据(例如,只要它的数据改变,DataSet就触发事件。)
图2.5 用户处理组件设计
l 控制一个特定用户处理的功能:开始,暂停,取消(4)。这些功能将被隔离保持,但可以和用户处理行为混合一起。例如,前面讨论的代码例子中,包含SaveToDataBase和ResumeCheckout方法。控制方法会加载UI请求的引用数据(如,填充Combobox的信息),这些数据是来源于数据访问逻辑组件(7)。或者控制方法委托这个工作给需要数据的用户界面组件(窗体,控件,ASP.NET页面)。
用户处理组件的一般建议
当设计用户处理组件时,考虑以下建议:
l 决定是否需要用户处理,而且把它从用户界面中隔离出来作为组件管理。大部分应用程序需要隔离用户处理是因为:应用程序中有许多的用户界面的对话框,或者应用程序中,用户处理需要自定义和从插件的方法中获得优势。
l 选择存储用户处理状态的地方:
Ø 如果过程运行在联机的方式下,为了长期运行处理的需要,存储中间状态在中央SQL Server数据库中;在脱机的场景下,存储它在本地的XML文件中,独立的存储器,或者本地SQL Server 2000 桌面引擎(MSDE)数据库中。在Pocket PC设备中,可以存储状态在SQL Server CE 数据库中。
Ø 如果过程是非长期运行,且不需要被恢复,你就持久化展台在内存中。对于构建富客户端的用户界面,可以保存状态在内存中。对于WEB应用程序,可以选择存储用户处理状态在ASP.NET的Session对象中。如果你正运行在WEB场地(farm),你要存储会话在中心状态服务,或者SQL Server数据库中。ASP.NET会清除SQL Server存储的会话,防止积累多余的数据。
l 设计的用户处理组件是可序列化的。这会有益于实现任何的持久化方案。
l 在用户处理组件中,包括异常处理,传播异常到用户界面。被用户处理组件抛出的异常,会被用户界面组件捕获和发布。异常的发布会在第3章(安全,运行管理和通讯策略)描述。
网络连通性和离线应用程序
在许多情况下,在网络连接无效时,应用程序需要支持离线操作。例如,许多移动应用程序,包括Pocket PC或者Table PC设备的富客户端,当用户和公司网络是不连接时,这些设备是能够运行的。离线应用程序必须依赖本地数据和执行它们工作的用户处理状态。当设计离线应用程序时,要遵守下面讨论的一般的指导原则。
在线和离线状态一定显示给用户。这个通常显示在状态栏,或者标题栏,或者在需要连接到服务器的用户界面元素周围带一个可视化的提示。
许多应用程序用户界面的开发要可以重用,有一点或者不用修改就可以支持离线场景。当离线时,应用程序不具有:
l 通过数据访问逻辑组件返回在线数据的权利。
l 同步调用业务过程的能力。结果,应用程序不知道是否调用成功,或者能使用任何返回的数据。
如果应用程序除了依赖同步获取数据和已知业务处理的接口之外,不能完全实现基于消息的接口连接你的服务(正如,今天的大部分应用程序),你会做出以下方面的错误想法:
l 实现一个只读式的本地缓存,缓存和用户活动引用有关的数据。然后,你可以实现一个离线的数据访问逻辑组件,除了是访问本地存储之外,这个组件完全实现了与访问服务边界一样的数据访问逻辑组件。可以在桌面MSDE数据库中实现本地缓存。这个方法提供了重用主SQL Server的架构和存储过程的能力。然而,MSDE会影响安装它的计算机的全局状态,从应用程序的配置中访问它,会带来不完全信任的麻烦。在许多场景下,为状态持久化的需要而使用MSDN有些过度,存储在XML文件中,或者持久化DataSet是更好的解决方案。
l 离线业务组件的接口的实现除了数据的提交,安排它的存储和传送依赖于像消息队列这样的消息的方式,其它的与你的业务组件一样。于是,这个离线组件会什么也不返回,或者返回一个预置值给调用者。
l 提供一个UI功能的方法来检查多余的业务行为,或者删除它里面的消息。如果消息队列被用于排列离线消息,需要在应用程序使用的队列上设置合适的权限。设计应用程序的事务处理调和基于消息的UI交互。要特别小心管理乐观锁和基于非时效的事务处理结果。执行刷新的一般技术是提交老的和新的数据,让有关的业务处理或者数据访问逻辑组件最终解决冲突。对于业务处理,要让包括关键数据的业务逻辑决定是否让数据通过。例如,当提交订单时,可以在产品ID和数量旁边包括产品价格。有关更多乐观锁的讨论,见MSDN上的“Designing Data Tier Components and Passing Data Through Tiers” (http://msdn.microsoft.com/library/?url=/library/en-us/dnbda/html/BOAGag.asp?frame=true)。
l 让用户持久化应用程序的用户处理状态到磁盘上,然后,以后再继续使用。
基于IP网络,无线标准的进化,802.11标准,IPv6,Tablet PC及其它技术的移动设备的出现将使无线网络更流行。无线网络的问题,伴随着今天的技术,不能保证所有区域都是高效连通。例如,建筑物,机器附近,或者其它因素会发生持久的和短暂的网络的“盲区”。如果设计使用在无线环境的应用程序,设计时要考虑为基于消息,离线应用程序,来防止全是意外的感觉和重试。例如,设计应用程序,方便一个离线的用户通过和网络连接时一样的界面输入数据,数据可以被存储本地数据库中,或者排队到稍后当用户连接成功时再被同步。SQL Server支持复制,可以用于松耦合方式下自动同步,允许在连接时下载数据到了离线设备上,在不连线时修改数据,然后,当连接时重新同步。微软的消息队列允许数据被封装在不连线设备的消息和队列中,当连线时,可以提交到服务边界的队列。然后,服务组件读取从队列中读取消息并处理它。使用本地队列或者SQL Server复制来处理用户输入服务的通讯,可以帮助减轻连通性的问题,甚至当应用程序在名义上是连线的。在一个更紧密耦合的方法被请求的地方,要使用事务处理,自定义登录,保证数据的完整性。
当数据同步发生在断线(或松耦合)应用程序和一个服务之间时,必须重视考虑安全事项:
l 消息队列提供它自己的基于Windows的认证模式。如果应用程序依赖于自定义,应用程序审核,客户端组件需要签入提交到服务的证明。
l 如果数据通过队列被提交,在服务端,客户端不能被匿名。
l 如果SQL Server复制被使用,可以需要一个特定的账户允许访问服务器上的SQL Server数据库。当复制的来源是从一个移动设备的SQL Server CE时,一个到IIS的安全连接站点包含必须建立SQL Server CE服务器代理。有关SQL Server复制的更多信息,见SQL Server和SQL Server CE的有资料。
l 如果网络通讯不是发生在HTTP连接之上的,需要使用SSL保护通道。
通知到用户和业务处理到用户的通讯
应用程序可能需要指定的事件通知用户。当Internet增加通讯容量时,需要有更多的可能选择来通知用户。当前,一般的技术包括e-mail,即时通讯,短信,调度等等。
即时通知包括需要可能的通知技术和现有服务的用法来探测联想到用户的可能方法。微软模式与实践已发布一个参考架构覆盖了这个场景。它在MSDN上,http://msdn.microsoft.com/library/en-us/dnenra/html/enraelp.asp。