|
该帖已经被评为精华帖
|
|
|---|---|
| 作者 | 正文 |
|
时间:2008-05-13
pig345 写道 taowen 写道 连接的获取和释放,和事务的管理是Service层的职责,无论Domain Model是贫血还是不贫血,都不会牵涉到连接和事务的管理。 如果做过多Client的WebServer项目的话就不会有太多疑问了。 这种项目中,web层本身只不过是众多client中的一个而已,另外还有GUI的 或 独立进程(用于系统间通信)的client,这些client并不能直接使用webserver里面的DomainObject,必须要一个Service/action层作agent,其实service层也可以发展成应用/界面逻辑(顺便控制事务边界),而Domain中是真正的领域相关的业务逻辑。 先不说你多client的项目是多么的罕见,就算你有GUI的独立client,你用什么方式和Server通信?说到底无非就是两种: 1、RMI方式 EJB就是基于RMI方式,但我相信你不会采用RMI方式,RMI不但复杂而且有太多限制,现在这种方式已经基本不被采用了 2、Web Service方式 好吧,Web Service方式你是不是还是需要Server端有一个Web层? 所以不管你是不是多个client? Server端必然都是通过Web层提供服务的,所不同的只不过是client是浏览器、手机、或者应用程序而已。所以Service层真的是必要的吗?恐怕未必吧。 你就看Rails的REST,人家只有Web层,那有怎样? 看看twitter吧,浏览器访问、手机访问、桌面软件访问、插件访问,其他网站API访问,消息访问,这client够多了吧,可是Rails需要什么Service层,什么agent层吗? |
|
| 返回顶楼 | |
|
时间:2008-05-13
从简单设计和重构的角度来看。最开始,应该是直接在action中调用domain。后来发现,需要抽出一个方法来调用domain,然后这个方法提供一个服务,支持action。后来发现,这个方法还需要一些额外的依赖和更多的实现内容,于是抽取出一个接口,注入一个对象到action中。后来发现,很多地方都需要这么做,那么就强制要求action必须依赖于service的接口,不能直接访问domain对象。这么一组抽象的接口,就构成了一个service层。
|
|
| 返回顶楼 | |
|
时间:2008-05-14
robbin 写道 pig345 写道 taowen 写道 连接的获取和释放,和事务的管理是Service层的职责,无论Domain Model是贫血还是不贫血,都不会牵涉到连接和事务的管理。 如果做过多Client的WebServer项目的话就不会有太多疑问了。 这种项目中,web层本身只不过是众多client中的一个而已,另外还有GUI的 或 独立进程(用于系统间通信)的client,这些client并不能直接使用webserver里面的DomainObject,必须要一个Service/action层作agent,其实service层也可以发展成应用/界面逻辑(顺便控制事务边界),而Domain中是真正的领域相关的业务逻辑。 先不说你多client的项目是多么的罕见,就算你有GUI的独立client,你用什么方式和Server通信?说到底无非就是两种: 1、RMI方式 EJB就是基于RMI方式,但我相信你不会采用RMI方式,RMI不但复杂而且有太多限制,现在这种方式已经基本不被采用了 2、Web Service方式 好吧,Web Service方式你是不是还是需要Server端有一个Web层? 所以不管你是不是多个client? Server端必然都是通过Web层提供服务的,所不同的只不过是client是浏览器、手机、或者应用程序而已。所以Service层真的是必要的吗?恐怕未必吧。 你就看Rails的REST,人家只有Web层,那有怎样? 看看twitter吧,浏览器访问、手机访问、桌面软件访问、插件访问,其他网站API访问,消息访问,这client够多了吧,可是Rails需要什么Service层,什么agent层吗? 您还真说对了,实际中就是用的RMI,还就因为这个使用了SLSB(当然web可以走近道local)。 04年的项目了,现在要赶时髦当然可以换成HttpInvoker、Hessian、Buriap、甚至JSON...... 不过慢着, 另: 我相信没人真的喜欢webservice, 不过即使是使用webservice,webservice也只是一个adapter而已(不含任何业务),同样SLSB也只是提供RMI的adaper,这些adapter都只是技术相关的,他们本身不能算作一个层,但他们却都需要使用service层来完成动作。 从ROR看REST的神奇之处在于,他将REST(系统间的接口)和正常的Web应用(人机接口)较完美的和谐成一套代码了。再加上ROR本来就没有分层,只有MVC。而JEE是强调分层,然后再在Web层使用MVC。在Rails里面别说找什么Service层,agent层,你连表现层,逻辑层,持久层都找不到。。。差异太大,先别参考了。 twitter我是实在不了解,抱歉了。 |
|
| 返回顶楼 | |
|
时间:2008-05-17
taowen 写道 和Linq还是不一样。Linq就是一种查询语言。你可以在colllection上做linq查询,也可以在数据库上做linq查询。但是以现在的实现而言。如果你认为tasks是collection,在Employee的task上做linq查询,那就是对collection的过滤。如果你认为tasks是数据库的表,在Employee上做linq查询,那就是sql查询。但是无法做到连接到数据库的时候做sql,不连接数据库的时候做过滤。也就是说,linq也会造成你的domain model和数据库绑定。
Linq 不是也有Linq to Objects嘛! 这个应该和DLinq有异曲同工之效 |
|
| 返回顶楼 | |
|
时间:2008-05-21
taowen 写道 我想robbin的意思其实是如果只有一个client,也就是在只有web层用它的情况下,service层除了啰嗦没啥价值,不如直接合并进web层。我对这个问题的看法是,要看service层中的具体服务到底有几个用户。如果到处都是只有一个用户的service,我们还要抽象出好多接口和对象来提供这些服务,不如直接在用的地方写就好了。在实际的,简单的web项目中,好像取消service层,让service层的用户也就是web层来实现事务控制安全控制好像更符合务实的精神。其实有三个选项:1、分层,2、分对象,3、分方法。简单情况下,取消service层,把起职责散布成web层的一些对象乃至成为action的一个方法,也未尝不可。不过没有具体实践,还要观察观察。
domain是不应该太贫血,但也没必要单纯为了rich domain而取消service层。 假设取消掉service层: 首要问题就是domain之间的交叉依赖,而在传统service层中,domain之间的关系从来都是交给具体service去完成的,service搞的再烂,也不会把domain搞烂; 然后是事务边界带来的bad smell(虽然将持久化设备注入给domain也不见得是坏事,但习惯上总觉得不那么好) 然后是如何为prototype bean进行注入; 最后还有诸如团队协作这样的麻烦,逻辑过于集中后,协同开发的确成为了麻烦事情。 所有这一切,只换来一个“逻辑集中”的优势,不用再考虑哪些方法该调用domain的,哪些是service的。而这些完全可以被合理的方法命名和编程规范所解决。 取消service层追求完全的rich domain,实在是弊大于利。 |
|
| 返回顶楼 | |
|
时间:2008-05-23
kabbesy 写道 taowen 写道 我想robbin的意思其实是如果只有一个client,也就是在只有web层用它的情况下,service层除了啰嗦没啥价值,不如直接合并进web层。我对这个问题的看法是,要看service层中的具体服务到底有几个用户。如果到处都是只有一个用户的service,我们还要抽象出好多接口和对象来提供这些服务,不如直接在用的地方写就好了。在实际的,简单的web项目中,好像取消service层,让service层的用户也就是web层来实现事务控制安全控制好像更符合务实的精神。其实有三个选项:1、分层,2、分对象,3、分方法。简单情况下,取消service层,把起职责散布成web层的一些对象乃至成为action的一个方法,也未尝不可。不过没有具体实践,还要观察观察。
domain是不应该太贫血,但也没必要单纯为了rich domain而取消service层。 假设取消掉service层: 首要问题就是domain之间的交叉依赖,而在传统service层中,domain之间的关系从来都是交给具体service去完成的,service搞的再烂,也不会把domain搞烂; 然后是事务边界带来的bad smell(虽然将持久化设备注入给domain也不见得是坏事,但习惯上总觉得不那么好) 然后是如何为prototype bean进行注入; 最后还有诸如团队协作这样的麻烦,逻辑过于集中后,协同开发的确成为了麻烦事情。 所有这一切,只换来一个“逻辑集中”的优势,不用再考虑哪些方法该调用domain的,哪些是service的。而这些完全可以被合理的方法命名和编程规范所解决。 取消service层追求完全的rich domain,实在是弊大于利。 似乎你说的service和我说的还不大一样,呵呵。 DomainObject之间的交互是不需要Service的。 |
|
| 返回顶楼 | |
|
时间:2008-05-26
taowen 写道 to coolnight:能不能举一个你们公司的Rich Domain Model的例子,以及它们是如何被大家废弃的。
sorry 看到这个较晚, 大致回复下: 我们的系统有很多模块组成, 各模块基本上通过数据库来共享信息。 主要的模块大致有: 核心系统(非web), 网站、 bbs、 网站后台,核心系统后台,BI, 推广员等等 原来的打算是写个rich domain model供各模块来使用,以便代码重用减轻个模块开发的工作量 一个简单的例子, User 原有 changePassword, getFriends, addFriend ... 等等方法 撇开配置以及获取User对象的复杂性不谈, 实际开发中发现, 这些东西重用的地方太少了, 对网站来说很好的rich domain model, 在网站后台里面就麻烦,很多方法在那里根本就是对后台 开发人员的干扰,而很多方法对核心系统、BI等等根本就毫无用处。 而且由于网站之类的web系统, 其功能变化很快, 今天一个样子明天完全有可能是另外一个样子了, 新招个策划都可能提出一堆的改动来, 还有很多临时性的功能, 最后真正在各模块之间共享 的就是最贫血的domain model, 基本上就是表的映射, 连关联都给废了各处自行维护了 因为系统数据量比较大,所以性能问题也受到比较多的关注, 在系统的关键部分, DBA说了算,OO靠边站 实际上我在几个公司呆过 也曾试图写出比较rich的domain model, 但是只要项目的需求变更的比较频繁, 那么rich domain model维护的成本就会很高, 而且想重用的想优雅的地方最终大部分变成了摆设, 而需求变更不频繁的项目, 太少太少了 |
|
| 返回顶楼 | |
|
时间:2008-06-30
看了这么久的领域模型,争论的真是没完没了。
难道就不能跳开这个领域模型或者还领域模型一个真正的身份,不要在贫血充血的来讨论了。 |
|
| 返回顶楼 | |








