论坛首页 Java版

将MS的PetShop3.2进行了比较大的重构

浏览 7525 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
时间:2005-02-04
1、重构原因:

微软的PetShop作为标准企业应用示例中的一个已经推出了很多个版本,目前的3.2版本和以前的版本相比较,平心而论确实有了很大的提高(1.0版本无论是体系结构还是代码编写都足可以作为一个很好的反面示例,呵呵)。但是还是非常的不理想,很多.net程序员居然把它视为以面向对象方式开发的.net应用的经典。为了纠正目前这种落后的实现方式(意识),做了这次重构,希望可以给大家做一个参考,实现的很仓促,肯定还有很多的不足,大家多提意见继续完善这个例子。(不过目前我觉得由于这个例子太过简单,不能真正做到示例OOD、OOP的目的。)

2、重构内容:
1、数据访问层由于改用nhibernate实现比重构前减少了1000多行代码。重构前支持oracle和MsSql,重构后可以支持任意的数据库。
2、业务逻辑层由领域模型,取代了重构前的“贫血的实体类” + “控制类”模式。
3、业务逻辑层不再直接依赖于COM+,更易于测试。(这个DEMO没有加入单元测试)

注:为了增强说明性和更好的进行对比,保持了原有的表示层和关系模型。实际上,我觉得最应该重构的就是它的关系模型,不过一个比较“烂”的关系模型可能会更好的示例nhibernate吧,呵呵。重构后的代码总量比重构前减少了三分之一。

3、系统环境:
1、.net1.1
2、nant0.85 + nantcontrib-0.85-rc1(这个我没放到包里,自己下载吧)
3、log4net1.2.0.30714
4、nhibernate-beta-0.6
5、sping.net0.6(不是目前官方release的那个,是通过目前cvs下载编译的。API和配置文件和以前都有些变化)

4、项目目录:
BLL: Domain Model
DAO: DAO
Web: 表示层
TransHelper:提供分布式事务支持能力(实现方式请参考 http://www.gotdotnet.com/team/dbox/default.aspx?key=2004-07-12T08:40:44Z)

注:其余目录有些是遗留的,我觉得还有用的就没删。

其他:

1、这个项目是用SVN管理的,如果想看到重构的“脚印”,可以给我发email(agilecoder@sina.com)
2、向大家推荐一款 NHibernate Query Analyzer,这个项目还处于发展中不是很成熟,但是想法很好。先加载好各种配置文件,然后你就可以随便写HQL语句了,它会自动即时生成SQL语句,即时提供错误信息。执行时会给出SQl Result(记录集)和HQL Result(对象图)。降低了编写和优化HQL的门槛和难度。( http://developer.berlios.de/projects/nqa/ )这个项目还是用SVN管理的,我很喜欢。
  • PetShop.rar (853.9 KB)
  • 描述: 源代码
  • 下载次数: 1717
   
时间:2005-02-04
看了一下你的重构,确实可以作为使用nhibernate的实例。
另外,有一些问题。
1)signIn的实现
/// <summary>
/// Method to login into the system. The user must supply a username and password
/// </summary>
public bool SignIn(){
// Validate input
if ((UserId.Trim() == string.Empty) || (Password.Trim() == string.Empty)) return false;

// Try to sign in with the given credentials
return ((ISignOnDAO)ObjectFactory.GetInstance("SignOnDAO")).SignIn(this);
}


public bool SignIn(SignOn signOn){
ISession session = Sessions.PetShop.OpenSession();
IList list = session.CreateQuery("from SignOn s where s.UserId = :userId and s.Password = :password")
.SetString("userId", signOn.UserId)
.SetString("password", signOn.Password)
.List();
session.Close();
if( list.Count == 0 ) return false;
SignOn result = (SignOn)list[0];
signOn.Profile = result.Profile;
signOn.Account = result.Account;
return true;
}
用户登陆是否有效,该是业务上的概念吧,但上面的代码表明该工作是DAO完成的。

2)TransHelper根据你提供的地址我没有找到相关实现。

3)由于没有找到transhelper的实现产生后面的问题
,事务控制你是否是放在DAO中进行的?
   
0 请登录后投票
时间:2005-02-04
partech 写道
用户登陆是否有效,该是业务上的概念吧,但上面的代码表明该工作是DAO完成的。


我同意你的意见。但是我必须在DAO层知道是否找到了对象,那个返回值也就是这个意思。不知道还可以怎样解决?

引用
2)TransHelper根据你提供的地址我没有找到相关实现。


那是Don Box's的blog,没想到居然变了,不好意思。你可以看TransHelper的实现,很简单。就是通过一个回调函数提供一个事务环境。在windows2003和winxp sp2或.net2.0中你可以有更好的实现方式。 http://blogs.msdn.com/florinlazar/archive/2004/07/24/194199.aspx

引用
3)由于没有找到transhelper的实现产生后面的问题,事务控制你是否是放在DAO中进行的?


事务最好在facade中控制。这个demo中在BLL中控制的分布式事务。其余的,比如像保存一个对象就是在DAO中实现的。
   
0 请登录后投票
时间:2005-02-04
//ISignOnDAO
SignOn FindByUserId(String userId);

public bool SignIn(){
// Validate input
if ((UserId.Trim() == string.Empty) || (Password.Trim() == string.Empty)) return false;

// Try to sign in with the given credentials
SignOn signOn = ((ISignOnDAO)ObjectFactory.GetInstance("SignOnDAO")).FindByUserId(this.UserId);
if(signOn == null)
return false;

if(this.Password != signOn.Password)
return false;

this.Profile = signOn .Profile;
this.Account = signOn .Account;
return true;
}

按照你的思路写的。DAO应当只充当数据访问的角色.

另外在DAO中实现事务,会导致无法使用UnitOfWork也就不能批量更新了。
赫赫

嗯,不错的NHibernate入门实例。
   
0 请登录后投票
时间:2005-02-05
我也想用Aop的方式在facade上进行事务管理,可惜目前没有什么好的解决方案。除非依赖COM+这样的入侵性很强的容器,不过我非常不愿意。或者要求BO继承自ContextBoundObject就可以自己写一个Aop的解决方式,我目前对于权限管理就是这么做的(这个DEMO中没有)。但是都不理想,因为我更愿意保持BLL层的类都是POJO的。

期待Spring.net或.net2.0可以有什么好的解决方法吧。
   
0 请登录后投票
时间:2005-02-05
spring.net aop是可以做事务管理的,当然要自己写,我上个项目就用了,不过更通用的还是要等spring.net 了
当前,spring.net data感觉不是很好
   
0 请登录后投票
时间:2005-03-10
现在快速学习JAVA。就为了了解spring和NHibernate的一些好的结构,这下有直接实例了,谢谢
   
0 请登录后投票
时间:2005-04-08
找到 用NHiberanate的同志了。安逸~_~
推荐大家一个NH的好工具。
ObjectMapper
http://www.objectmapper.com/download/
   
0 请登录后投票
论坛首页 Java版

跳转论坛:
JavaEye推荐