NET与J2EE目前的差距主要不在技术,而是缺乏一套完整的企业级架构。虽然通过微软专家的精心设计能够使.net企业应用的性能胜过J2EE,但对我们广大开发者和中国的软件企业而言,应用水平还是很低,还无法全面的应用.net
的技术优势建立一个通用性的架构。
近日看了Rockford Lhotka的《VB.net业务对象指南》,作者在书中阐释的CSLA架构令我深受启发,颇为喜爱。遂按其思路以C#重新编了一遍,并生成详尽的中文开发文档,供我的开发团队使用。现摘抄部分于此,与各位.net架构爱好者共分享。
CSLA全称Component-based,Scalable,Logical,Architecture,是一种可灵活配置的分布式、面向对象的应用程序架构。
主要具有以下特点:
1.n级撤销功能
2.跟踪违反业务规则
3.跟踪对象是否发生变化
4.支持windows和web数据绑定
5.分别针对业务开发和UI开发人员的一种简单抽象模型
6. 支持微软的集成安全性或基于表的安全性
n 级撤销功能

本功能可以实现保存多个编辑状态,在需要时多次撤销操作,返回初始状态。
如图所示, UndoableBase 继承BindableBase的 IsDirtyChanged 事件,跟踪对象是否发生变化。
UndoableBase 通过CopyState 方法对业务对象中未标记 [NotUndoable] 的变量拍摄快照。 UndoChanges
撤销修改,返回到最后一次调用CopyState()前的状态 。 AcceptChanges 接受修改,上一次CopyState缓存的快照将失效
。
BusinessBase 继承UndoableBase,使用 BeginEdit 间接调用CopyState, 为数据保存快照。使用
CancelEdit 间接调用 UndoChanges撤销操作,返回到上一次调用BeginEdit以前的状态。 ApplyEdit
应用操作,调用后将无法撤销上次调用BeginEdit以后的修改。业务开发人员只需通过显式的调用这三个方法即可实现n级撤销功能,无须考虑其细节。
NotUndoableAttribute 用于标记字段使它不支持撤销操作避免不必要的内存开销,比如大的多媒体变量。
跟踪违反业务规则

Rule 是用来存储的业务规则名称和描述的结构体
RulesCollection 是 Rule 的集合,通过继承 CSLA.Core.BindaleCollectionBase
支持绑定。
RulesCollection 是 BusinessBase 的私有变量,可以通过只读属性 BrokenRules 访问。
用法举例:
public string Name
{
get{return name;}
set
{
//value.length==0作为是否违反业务规则的判断条件,
//为true(说明姓名为空值)添加进违反规则列表,为false从规则列表移除
BrokenRules.Assert("NameReq","姓名不可为空值",value.length==0);
name=value;
}
}
当 BusinessBase 的存在违法规则的数目不为零时, IsValid 属性为false,此时将不能进行更新。
由于RulesCollection 支持绑定,因此可以把违反规则的描述绑定在控件上作为显示。
跟踪对象是否发生变化

跟踪对象变化就是跟踪对象中变量值是否发生改变,若改变则意味着“变脏”,IsDirty。
“变脏”作为是否对数据库进行更新的依据,避免了不必要的数据库更新操作。
BindableBase 通过[Serializable()]标记为可串行的抽象基类,定义事件 IsDirtyChanged
并标记为[field: NonSerialized],可以避免任何处理事件的对象如windows窗体被串行。
通过 OnIsDirtyChanged 触发 IsDirtyChanged 事件 。
BusinessBase 通过继承 UndoableBase 间接的继承了 IsDirtyChanged 事件,通过 MarkDirty
方法标记数据变脏,并触发IsDirtyChanged事件。

BindaleCollectionBase 继承 System.Collections.CollectionBase ,实现
IBindingList 接口, 提供基本的集合功能和数据绑定支持 提供非串行化事件 ListChanged 跟踪集合内容变化。

如图, BrokenRules.RulesCollection , BusinessCollectionBase , ReadOnlyCollectionBase
都通过继承BindaleCollectionBase获得跟踪对象变化和数据绑定的支持。
支持windows和web数据绑定

BusinessBase 实现 IEditableObject
接口提供提交或回滚对用作数据源的对象所做更改的功能。

BindaleCollectionBase 通过实现 IBindingList
接口,提供绑定支持所需的功能。

如图, BrokenRules.RulesCollection , BusinessCollectionBase , ReadOnlyCollectionBase
都通过继承BindaleCollectionBase获得跟踪对象变化和数据绑定的支持。
简单抽象模型
CSLA封装了所有底层实现细节, 为业务开发和UI开发人员提供一种简单而强大的开发模型。
业务类开发
业务开发人员可以像开发本地对象一样开发业务类对象,无须考虑未来这个对象是在哪运行的。
所有的开发围绕业务进行,通过统一的接口编写四个数据访问方法实现持久性,剩下的工作就是在公共属性和方法中编写业务规则和逻辑供UI开发人员使用。
通过架构本身的提供的功能轻松实现对用户权限的控制和对违反业务规则的跟踪。
提供 NameValueList , SmartDate , SafeDataReader 等实用工具类简化开发,提高开发速度。
UI开发
CSLA架构支持WEB和Windows数据绑定,UI开发人员可以利用原有的数据绑定开发的经验。
较少的业务类接口实现丰富的功能,并且所有的业务类有一致的使用风格,轻松上手。
支持微软的集成安全性或基于表的安全性
CSLA支持windows集成安全性和基于表的安全性两种方式。
可以通过配置文件选择其中的一种。
关于windows的集成安全性依赖于微软的相关技术,具体方法参看微软的技术材料。
本文档的重点是介绍基于表的安全性。

首先通过建立Users、Roles两个表分别存储用户信息和用户的角色列表。

BusinessIdentity 继承 ReadOnlyBase 并实现 IIdentity 接口。
它本质上是一个业务类,通过书写数据访问方法实现从 Users表验正,通过后读取Roles中用于所属的角色列表。
BusinessPrincipal 包含一个BusinessIdentity 对象,通过静态方法 Login 登陆数据库加载用户和用户的角色,并通过实现
IPrincipal 接口支持安全性。
开发人员使用时只需使用 Login 即完成了验证用户和角色,并加载为当前线程的安全用户信息的全部过程。
编写业务类时在需要检查用户是否是具有该操作权限的角色时,比较当前线程的安全用户信息。
如下所示
public static void DeleteCustomer(string customerID)
{
if(!System.Threading.Thread.CurrentPrincipal.IsInRole("Administrator"))
throw new System.Security.SecurityException("非法用户操作!");
DataPortal.Delete(new Criteria(customerID));
} |