一个四层应用体系架构 [CBOFramework C# Beta 1 ]
小气的神
2002-5-12
Article Type: Overview
难度等级:7/9
版本:3.22
有关dotNET下的应用体系构架的话题,我们可以明确的从某一点开始,但是可能没有结束的那一点,永远没有:) 一大批原来COM+的程序员开始在COM和dotNET之间走钢丝,一方面忙于将重点和应用向dotNET构架上转移,一方面还要照顾着原来的COM。最后这些程序员将在经历了某一个学习曲线之后坦然的面对两者,掌握了如何分别和两者交互和周旋的技巧。但是问题可能才刚刚开始,因为他们很快开始问这样的问题:今后的程序该怎么写,程序的构架是怎样的?
太多的程序构架模型,让他们开始有些眼花缭乱了,新的概念和技术似乎太多了,掌握了这些概念之后会发现一种无从下手的感觉,你不知那一种方式是相对最好的。Paul D. Sheriff (PDSA, Inc.)在4月底的MSDN上发表了Designing a .NET Application( Updrading to Microsoft.NET )的文章,里面有总结了目前dotNET下常用的几种程序构架和各自的特点。事实上,当你使用ADO.NET, ASP.NET, COM+, Web Services , XML, Remoting, DCOM/SOAP/HTTP就可以象他那样组合出不下20种的三层或多层构架形式。另外还可以加上MSMQ 和SQLXML。
一部分程序员已经开始有些怨言,相对于J2EE的严格规范,dotNET下的架构似乎过分开放了。相信这种状态还会持续一段时间,Microsoft也需要经历一个优化和整合的过程才能做出富有成效和建设性的指导和建议。这之前的时间里,对于应用架构的选择问题可能会落到ISV和开发人员身上。
经过一段时间的发展过程中,有一些原则已经被总结出来,并且被越来越多的应用起来,比如:
1. 使用统一和强健的DAL(Data Access Layout)和存储过程,使得数据服务层更加接口化和高效能。
2. 应用面向对象分析和设计将Business层组件和对象化,从而顺利使用设计模式,提高可重用性。
3. 设计时充分考虑面向Web Services的接口和功能。
4. 使用dotNET接口和属性将三层更加细化和分层以提供更高层次的抽象。
5. 层与层之间的接口越来越“松散耦合”,稳定性和灵活性明显获得提高。
6. 使用COM+的比重开始降低,COM+被精确的应用分布式、多数据库和核心中间件上。
7. 商务逻辑更加细化,一定比重的商业逻辑的实现从商业逻辑层移到表现层,由多层共同完成。
8. Web Server开始慢慢成为离客户端最近的业务逻辑代理和资源、权限的控制器。
9. WebForm和WinForm提供了丰富的UI,使得表现层有更多精力处理用户会话、登录、权限等问题。
10. XML和Schema被更多的应用在设计中,往往成为系统中多层之间联系和通讯的“胶水”和介质。
下面要说的这个四层应用体系架构源于《Designing Solutions With COM+ Technologies》中的11章的一个实例。Wade Baron将原来的三层结构进行了调整,其一是实现客户端的对象化访问,其二是将业务逻辑层分为事务服务层和对象服务层,对象服务位于表现层(客户端),事务服务在原来的业务逻辑层,位于服务器端。具体的见下图:
CBOFramework框架体现了上面的2,4,7,10的一些特征,特别是引入了面向对象的设计和分析,结束了返回ADO记录集的Business对象的混乱表现,使得表现层有更多的精力处理自己的逻辑。另外一方面由于实现了抽象和对象化,使得设计时可以应用目前已知的多种设计模式。
CBOFramework中也使用了Collection的技术和概念,但它不同于早先Mike McClure (Microsoft)和Leo Romano(Sierra System Group Inc)描述的ECC(Engine-Collection-Class) Framework。CBO也可以应用Object Factory或其他的设计模式,但作为核心设计上CBO没有强调设计模式,而是体现了接口编程和面向对象分析技术。在表现上CBO没有ECC那么直观和有针对性,我个人认为CBO更加强大和先进,负载上比ECC的Collection传递要小许多,并且由于是接口设计更容易扩展,比如可以使用dotNET新的Remoting、SOAP协议作为分布协议,当然两者并不冲突,理解ECC对于理解CBO有很大帮助,因为两者有些是相同的。
由于篇幅有限,我将不翻译原文的设计思路和描述,强烈建议你从原著和书中获得更详细的设计思想和内部流程。本文将提供原来没有的类图表示(这是从Visual Studio.NET中反向工程我的代码获得的)我将整个框架按dotNET的方式以C#重新编写(原来作者提供一个Visual Basic版本的Project),表现层,我没有使用作者的,而是重新写了一个简单的进行测试,(我更希望未来直接使用作者的例子,因为他的客户端实现更好和更完整)。另外,Shippers对象(三个类)我没有完成,因为理解框架后一些对象的实现基本上是Copy/Paste的过程。例子使用的数据库是SQL Server和MS Access数据库中著名的Northwind的样本数据库,未进行删改。
系统需要的环境:Visual Studio.NET EN RTM+, SQL Server 2000 SP2.
细节和实现:
整个框架定义了四个接口、一个对象持久性的实现和一个Object Collection的实现。
接口:IPersistObjectStream和IObjectStream是客户端接口
接口:IPersistTransStream 和 ITransStream 是服务器端接口。
CBOCollection是一个Object Collection实现,被用于实现对象集合。
所有对于每个对象的集合比如:Customers、Orders等等都必须一个集合对象,由于dotNET不提供generic porgramming特性(templates),那么为每一个现实对象实现一个Type-safe的集合对象将是痛苦的。这里我使用了Chris Sells提供的CollectionGen工具,产生了一个Object类型的通用CBO Object Collection。(生产速度很快,而且很方便但不是Type-Safe的Collection,这意味着可能会有一定类型转换的性能消耗,太多集合对象,一个一个产生似乎太….)
CStream 实现IObjectStream和ITransStream ,这个类实现了将客户端的对象保持到数据库中(对象持久性)。目前这个类借助XML,使得客户端将通过透露的接口把对象序列化到这个XML流中,并且可以进行读取;同时服务器端事务对象可以从这个对象透露的接口中读取数据。
事务服务层(Transaction Services)的对象
所有的事务层对象都必须实现IPersistTransStream,这个接口被流对象调用,用来将数据写到数据库中。下面是一个Customers事务对象的实现
对象服务层( Object Services)的对象
对象服务层的对象:对象和对象集合都必须实现IPersisObjectStream接口。这个接口主要由流对象使用,用来从XML流中加载对象和将对象状态保存到XML数据流中。
客户端:
使用CBOFramework的好处可以在客户端得到最好的体现,现在表现层用户可以将自己的精力完全放在表现层的界面和业务逻辑流程的处理上,而不用理会记录集字段的次序和类型转换。表现层的用户可以更加容易的使用这些和现实中类似的对象来进行编程和操作,达到和业务流程的对应。
典型的DNA架构
CBOFramework
获得对象
Dim RetRst as AD.ORecordset
Dim Customer as Object
Set Customer = CreateObject(“Custom”)
set RetRst =
Customer. GetByCustomerID( txtSearch.Text )
CCustomers m_oCustomers = null ;
CCustomer m_oCustomer = null
m_oCustomers = new CCustomers() ;
m_oCustomer =
m_oCustomers.GetByCustomerID( txtSearch.Text )
绑定
txtCompany.Text = RetRst(“Company”)
txtContact.Text = RetRst(“Contact”)
txtTitle.Text = RetRst(“Title”)
txtAddress.Text = RetRst(“Address”)
txtCity.Text = RetRst(“City”)
txtCompany.Text=m_oCustomer.Company;
txtContact.Text= m_oCustomer.Contact ;
txtTitle.Text = m_oCustomer.Title ;
txtAddress.Text = m_oCustomer.Address ;
txtCity.Text = m_oCustomer.City ;
修改
lret = Customer.UpdateAddress( Addre)
m_oCustomer.Address = Addre ;
m_oCustomer.Save() ;
删除
lret = Customer.DeleteCustomer ( CuID)
m_oCustomer.Delete() ;
新增
lret = Customer.AddNew ( A1,A2,A3…)
m_oCustomer = new CCustomer() ;
m_oCustomer.Campany = A1 ;
m_oCustomer.Contact = A2 ;
………
m_oCustomer..Save() ;
当然这里简化了一些,典型DNA架构下的一些记录集的检索、计算、求和等等被简化了,事实上这些逻辑经常乱七八糟的排在表现层的代码中。CBOFramework最终达到我们的目的:提高可重用性,代码更加简洁和易于维护。
未来:
这是CBOFramework的第一个版本,其目标是理解其架构并将其在dotNET平台上实现。必须承认这个版本是非常原始和简陋的,仍有许多没有完成。它仅仅阐明了整个框架,展示了对这个框架的一个实现和应用,我想未来会对CBOFramework做更多的补充和调整,比如下一个版本会增加下面一些特性:
1. 目前还不能算是真正的分布式,所有的事务服务层对象还没有从ServicedComponent继承(我注释了这可能不是最终方案),那么对象服务层和事务服务层的通讯(非本机)还必须通过DCOM,也就是需要在COM+进行打包部署。下一个版本会实现在对象服务层和事务服务层实现Remoting协议通讯,当然最好同时兼容DCOM。
2. 实现一个通用的DAL或DAO (Data Access Object),统一事务服务层对于数据库的访问方式,使之兼容MSSQL,XML、OLEDB和SQLXML。
3. 完善应用的实例,并且通过使用一个创建类型的设计模式,使原来的作者的VB实例(COM用户)可以透明的使用新的组件。另外增加ASP.NET的实例。
4. 将框架中使用的XML函数进行整理,统一成一个XMLHelp类便于重用。
5. 基于上述CBOCollection的描述,将这个类的实现从CBOFramework的命名空间中移出来,放到次一级的命名空间,便于以后使用的框架的用户决定实现自己的Object Collection类。
总结:
以上我们基本讨论一个和原来Windows DNA相关的体系结构的改进版本:一个四层的结构。这种结构调整了原来常见的三层结构的分类并引进了面向对象的设计和分析。另外CBOFramework使用接口和流的概念借助XML实现了一个对象持久化(对象到关系数据库的映射)。整个CBOFramework充分使用了接口定义,所以非常利于扩充和改进。个人认为理解这个框架本身比使用这个框架意义更加重大;虽然它还十分单薄,但我想这将一个不错的开始。
源代码:
特别:
本文原创CSDN署名首发,所有文字和图片版权所。未经授权请勿传播、转载或改编
如果有问题或建议,请发电子邮件给new2001@msn.com
CBOFrameworkLib 中源代码属于演示用途,没有任何条款和许可说明,任何人可以任意使用。
《Designing Solutions With COM+ technologies》一书的附赠光碟中有原VB版本的源代码和电子书。该书中文版《COM+技术解决方案设计》已由机械工业出版社出版, 2001.09
最后感谢CSDN提供源代码空间