出处:http://newfay2007.spaces.live.com/blog/cns!58E787F39DB08857!275.entry?_c11_blogpart_blogpart=blogview&_c=blogpart
近来研究了一段时间的duwamish,所获颇多,在此写些学习心得,与大家分享,望大家指教。
关于购物车
近来研究了一段时间的duwamish,所获颇多,在此写些学习心得,与大家分享,望大家指教。
duwamish是微软.net框架下的一个经典的企业级分布式应用解决方案示例,我分析的是C#/ASP.NET版本的。分为四层:表示层(Web)、业务外观层(BusinessFacade)、业务规则层(BusinessRules)、数据访问层(DataAccess)。一般而言分为三层便足以,duwamish分四层自有它的道理,因为有些操作并不涉及复杂的业务逻辑,这些操作只需直接调用数据访问层的接口便可,譬如获取商品类别的列表。而一些较为复杂的操作,譬如生成订单,此间涉及总价计算、运费计算、税额计算等,运费、税额等规则的定制,可以在业务规则层中进行。
duwamish的层与层之间传递的并非简单的数据类型,譬如int,String之类,而是自定义的继承于DataSet的一组业务实体对象,这些实体类在duwamish的common子项目当中,分别为CategoryData、BookData、CustomerData、OrderData。这样做的好处是降低了层与层之间的耦合,使得层与层之间更为独立,便于项目组的分工,因为各层之间交互的数据都是统一格式的业务对象,每层的组员只需根据预定的计划,完成本层所要提供的功能即可,而不必考虑数据交互的兼容性。
关于各层的分工如下:
一、负责表示层的组员只需着眼于页面美工,调用业务层接口函数,以及将客户端数据封装人业务实体对象当中然后传与业务层处理。
二、负责业务层的组员起着承上启下的作用,将来自于表示层的业务实体对象进行拆包,而后根据各种业务规则进行相应处理,再将之重新封装,传入数据处理层,或者反过来,将数据处理层传来的业务对象封装再传与表示层。
三、负责数据处理层的组员,完成如下工作:对来自业务层的数据对象进行解封装,调用存储过程将数据写入数据库,以及相应的逆过程,调用存储过程读出数据,进行封装,再传递给业务层。
各层之间就是一个 “
装箱-拆箱-装箱-拆箱” 的过程。
这当中存在一个疑问:为何要用继承自DataSet的类,而不自行定义一些普通类?查了些资料,是说,继承自DataSet并加之[SerializableAttribute] 属性,乃是为Remoting技术部署提供可序列化为Binary或者SOAP的数据类型,因为DataSet类支持XML。而且这样做也可减少与数据库的依赖。关于这一点,涉及Web Service的内容,现在知之甚少,以后再加以阐述。
百言莫如一图,我画了张duwamish的体系结构图,见下:
还有各业务实体的内部表结构图,如下:
从图中可见业务实体类中的表结构与数据库中的物理表结构并非一一对应,因为数据库中的物理表的构造以及相互之间的联系有数据库理论方面的讲究,而在业务逻辑层面需要对从数据库中读出的数据进行再处理,以便其他层的调用,因此业务实体类中的逻辑表结构并不一定要与数据库中的物理表结构相同。
关于序列化
不明白。
不明白。
关于购物车
购物车一般采取两种做法:
其一,在数据库中创建购物车表,每次对购物车的操作都是对数据库的读写,这涉及I/O操作,在效率上比较低。
其二,构造购物车类,为每位顾客分配一个购物车对象,将该对象存放于Session当中,这样在内存中对购物车中的数据进行操作,效率而言高之于方案一,然而,这增加了服务器的负担。
duwamish采用的方案二,程序当中构造了一个Cart类,继承自ISerializable,支持序列化,类中定义了添加、更新、删除商品等操作。
关于性能优化
在看代码的过程中,我注意到duwamish在性能优化方面的一个细节,就是使用StringBuilder代替String类对象的“+”操作,比如:
一:
String str = "";
String str = "";
for(int i=0; i<10000; i++)
str += i.ToString();
二:
StringBuilder str = new StringBuilder();
for(int i=0; i<10000;i++)
str.Append(i.ToString());
方案二之效率明显较方案一为高。概因String类对象是不可改变的,一旦创建就无法再对其值进行修改。对String对象的重新赋值在本质上是重新创建一个String对象,再赋予新值。而StringBuilder类可避免重新创建String类对象所造成的性能损失。
另外,使用using,能使得创建的Customers在使用后马上被释放。
using (Customers customersAccess = new Customers())
{
result = customersAccess.UpdateCustomer(customer);
}
{
result = customersAccess.UpdateCustomer(customer);
}
关于性能优化还涉及配置文件,颇为麻烦,不写了。
其他细节
duwamish中用了大量的Server.HtmlEncode,对从数据库中读出的数据进行编码,因为数据库中可能存在因人为破坏等原因而产生的恶意HTML代码,此些代码若不经编码而直接传与客户端,将对客户端产生破坏,而这点我们在平时的编程中很容易忽视之。
关于基于duwamish的扩展
学乃是为了以致用。duwamish提供的是一条思路,一个解决方案的构架,看明白了其实也无非就是一个简单的项目。我们要开发实用的项目,还得在这个框架上进行大量的工作,比如需要有后台管理系统,涉及到商品类别的管理、商品的管理、会员管理、订单管理、资金管理、系统设置等。这些我也正在将之付诸实践。
还有其他很多方面的东西可以学习,网上有很多资料,于此我也不赘述。