锁定老帖子 主题:再次小结领域模型的种种观点
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2005-12-15
firebody 写道 robbin 写道 to firebody:你举的代码例子是一个胀血的模型,可不是Martin的充血模型。Martin的充血模型中可不允许你直接在Web Action中使用Teacher的业务方法。而是必须使用Service来隔离。
to partech:你好像也误解我的意思,我可从来没有说DAO就是domain logic,这是两码事。 赫赫, 这个必须有点莫名其妙,增加多中间一层和少一层一定要套得这么清楚吗? 对于可能的复杂业务,确实应该通过Service来做的,不过我不喜欢叫它Service,我喜欢称之为LogicObject。 如果你觉得胀血,我想分离到Service Object也是一种很好的重构。 哈哈 明白你的观点了。其实你的观点就是胀血模型,只不过在你的胀血模型中,domain object被分为了两类:一类是带有持久化属性的domain object;另一类是不带有持久化属性的domain object。对于带有持久化属性的domain object来说,他们是有自己状态的,难以直接使用spring的事务管理,必须通过其他方式(例如你设想的方式)施以事务管理和DAO DI;对于那些不带持久化属性的domain object来说,他们是无状态的,用来表达多个持久化domain object的协作,他们是Singleton,可以直接被Spring管理。 不过你的模型当中也有矛盾的地方:一个持久化的domain object,有些操作是带状态的,例如account.withdraw(...),取钱动作是有状态的,关联到某个account对象上,有些操作account.findAccountById(...),这就是无状态的操作,和某个具体的account毫无关系,这种操作要么定义为静态方法:Account.findAccountById(...),要么定义为Singleton的,通过Spring DI。 这两种操作(有状态和无状态)是不一样的,只有有状态的操作才紧密的和domain object关联,那些无状态的操作分离出去作为helper类更加合理,也更OO一些,所以你的划分逻辑操作的标准也不够OO。 |
|
返回顶楼 | |
发表时间:2005-12-15
讨论中spring team的人出来说可以做动态织入,没看到?
引用 No Additional Compilation Step Necessary
Posted by: Rob Harrop on December 13, 2005 in response to Message #193702 2 replies in this thread It's sad that the new approach require additional compiling step, which I want to avoid. No additional compilation step is required - you can use the Load-Time Weaving (LTW) capabilities of AspectJ to weave in the configuration aspect during application startup. Rob --------------------------- Interface21 - Spring from the Source http://www.springframework.com |
|
返回顶楼 | |
发表时间:2005-12-15
nihongye 写道 讨论中spring team的人出来说可以做动态织入,没看到?
动态织入?spring aop可以直接intercept构造函数?我印象中spring aop是纯粹dynamic proxy based,应该不能拦截构造函数啊。 |
|
返回顶楼 | |
发表时间:2005-12-15
oh。原来aspectj现在支持动态织入了。
|
|
返回顶楼 | |
发表时间:2005-12-15
落后了。。。。。
|
|
返回顶楼 | |
发表时间:2005-12-15
robbin 写道 firebody 写道 robbin 写道 to firebody:你举的代码例子是一个胀血的模型,可不是Martin的充血模型。Martin的充血模型中可不允许你直接在Web Action中使用Teacher的业务方法。而是必须使用Service来隔离。
to partech:你好像也误解我的意思,我可从来没有说DAO就是domain logic,这是两码事。 赫赫, 这个必须有点莫名其妙,增加多中间一层和少一层一定要套得这么清楚吗? 对于可能的复杂业务,确实应该通过Service来做的,不过我不喜欢叫它Service,我喜欢称之为LogicObject。 如果你觉得胀血,我想分离到Service Object也是一种很好的重构。 哈哈 明白你的观点了。其实你的观点就是胀血模型,只不过在你的胀血模型中,domain object被分为了两类:一类是带有持久化属性的domain object;另一类是不带有持久化属性的domain object。对于带有持久化属性的domain object来说,他们是有自己状态的,难以直接使用spring的事务管理,必须通过其他方式(例如你设想的方式)施以事务管理和DAO DI;对于那些不带持久化属性的domain object来说,他们是无状态的,用来表达多个持久化domain object的协作,他们是Singleton,可以直接被Spring管理。 不过你的模型当中也有矛盾的地方:一个持久化的domain object,有些操作是带状态的,例如account.withdraw(...),取钱动作是有状态的,关联到某个account对象上,有些操作account.findAccountById(...),这就是无状态的操作,和某个具体的account毫无关系,这种操作要么定义为静态方法:Account.findAccountById(...),要么定义为Singleton的,通过Spring DI。 这两种操作(有状态和无状态)是不一样的,只有有状态的操作才紧密的和domain object关联,那些无状态的操作分离出去作为helper类更加合理,也更OO一些,所以你的划分逻辑操作的标准也不够OO。 :oops: 我觉得你还不明白,这样的模型是可以充血也可以胀血的。 胀血重构就可以回到充血,胀血这个名词不应该出现,如果硬是要给它一个定义的话,我觉得倒是可以说是 缺乏重构(一个类包含太多逻辑)的领域模型。 |
|
返回顶楼 | |
发表时间:2005-12-15
什么血模型的名称之争没有意义,但是请回答我这个问题:
引用 不过你的模型当中也有矛盾的地方:一个持久化的domain object,有些操作是带状态的,例如account.withdraw(...),取钱动作是有状态的,关联到某个account对象上,有些操作 account.findAccountById(...),这就是无状态的操作,和某个具体的account毫无关系,这种操作要么定义为静态方法: Account.findAccountById(...),要么定义为Singleton的,通过Spring DI。
这两种操作(有状态和无状态)是不一样的,只有有状态的操作才紧密的和domain object关联,那些无状态的操作分离出去作为helper类更加合理,也更OO一些,所以你的划分逻辑操作的标准也不够OO。 |
|
返回顶楼 | |
发表时间:2005-12-15
robbin 写道 什么血模型的名称之争没有意义,但是请回答我这个问题:
引用 不过你的模型当中也有矛盾的地方:一个持久化的domain object,有些操作是带状态的,例如account.withdraw(...),取钱动作是有状态的,关联到某个account对象上,有些操作 account.findAccountById(...),这就是无状态的操作,和某个具体的account毫无关系,这种操作要么定义为静态方法: Account.findAccountById(...),要么定义为Singleton的,通过Spring DI。
这两种操作(有状态和无状态)是不一样的,只有有状态的操作才紧密的和domain object关联,那些无状态的操作分离出去作为helper类更加合理,也更OO一些,所以你的划分逻辑操作的标准也不够OO。 如果让我来选择的话,我会把它放到一个QueryDAO中。 |
|
返回顶楼 | |
发表时间:2005-12-15
好吧,那么我是web程序员,我从页面传一个id过来,要先load一下该Account,显示account的信息。那么请问:你提供给我什么API?是
account.getAccountById(id); 还是 accountService.getAccountById(id); 还是 accountDao.getAccountById(id); ? |
|
返回顶楼 | |
发表时间:2005-12-15
robbin 写道 好吧,那么我是web程序员,我从页面传一个id过来,要先load一下该Account,显示account的信息。那么请问:你提供给我什么API?是
account.getAccountById(id); 还是 accountService.getAccountById(id); 还是 accountDao.getAccountById(id); ? new Account(id); |
|
返回顶楼 | |