精华帖 (0) :: 良好帖 (2) :: 新手帖 (3) :: 隐藏帖 (4)
|
|
---|---|
作者 | 正文 |
发表时间:2011-01-13
gdpglc 写道 peterwei 写道 service里的方法: savePayment(Payment p){ //我们都是调用相关service类操作 paymentDao.save(p); //封装消息通知接口支付 messageService.sendMessage(message notice); logService.log(...); } 实际的支付接口方法可能是: receiveMessage(..){ //parse message userService.findAccountByUser(...); billService.bill(XXX); accountService.save(account); } 这算不算:给某个业务对象发消息,让它做去?是不是面向对象? 那么具体操作的复杂逻辑肯定要一步步来,总要有个地方做。 关键是业务逻缉是由谁来做。 Service Dao是过程对象,换句话说,这只是功能的简单划分。Server和Dao都可以是单粒的,几乎没有属性,这样的对象相当于一个名子空间。 总之:业务逻缉=业务过程+业务数据 就是面向过程的。 我之前说业务对象,说的不准确。我是指领域对象。比如:对于支付,会有Account,那Account就是领域对象。要让它充血才是采用了面向对象分解。 那我倒想听听你的充血实现方式,那么你给我举个充血OO的支付代码实现。充血有什么优势?为什么一定要用? 1.用户支付 2.消息通知支付接口 3.接收消息 4.找出账户 5.计费相关 6.保存账户 |
|
返回顶楼 | |
发表时间:2011-01-13
最后修改:2011-01-14
没人说一定要用。而且现在大部份人都没用。因为它难用,而且大部份人用的是Spring。
好处坏处看经典吧,我说不出新东西。 你这个例子,好象不明显,而且我也不太理解你的需求。我举个别的吧,比如转帐。 从 A帐户取transferNum到B。 以下代码,只表语意 面向过程的方式: //transaction begin Account a=AccountDao.find...... a.setBalance(a.getBalance-transferNum); AccountDao.save(a); Account b=AccountDao.find...... b.setBalance(b.getBalance+transferNum); AccountDao.save(b); //transaction end 面向对象的方式: Account类提供如下方法: void transferTo(Accout a,transferNum){ this.balance-=transferNum; a.balance+=transferNum; } 然后Service 里这样用: //事务开始 Account a=获得Account Acconnt b=获得Account a.transferTo(b,50); //事务结束 |
|
返回顶楼 | |
发表时间:2011-01-13
很乱,不知道这说啥。
说我的看法,楼主的意思是想问,框架怎么才能与业务模型相互OO. 1:没有哪个软件是完全OO的,总有一些不是。比如Service在于给业务模型发消息时。保存数据到数据库时。 2:借助spring,hiberante等框架没办法很好的实现充血模型,这个讨论很久了。 |
|
返回顶楼 | |
发表时间:2011-01-13
gdpglc 写道 没人说一定要用。而且现在大部份人都没用。因为它难用,而且大部份人用的是Spring。
好处坏处看经典吧,我说不出新东西。 你这个例子,好象不明显,而且我也不太理解你的需求。我举个别的吧,比如转帐。 从 A帐户取transferNum到B。 以下代码,只表语意 面向过程的方式: //transaction begin Account a=AccountDao.find...... a.setBalance(a.getBalance-transferNum); AccountDao.save(a); Account b=AccountDao.find...... b.setBalance(b.getBalance+transferNum); AccountDao.save(b); //transaction end 面向对象的方式: Account类提供如下方法: void transferTo(Accout a,transferNum){ this.balance-=transferNum; a.balance+=transferNum; } 然后Service 里这样用: //事务开始 Account a=获得Account Acconnt b=获得Account a.transferTo(b,50); //事务结束 ok,我终于理解你的意思了。说得那么绕。哈哈。你直接说充血,就是在Domain Object里把逻辑操作和数据都封装在一起。但这种做法,我是持反对观点的,也不提倡。 action-->service(什么也不做,只管事务之类)-->domain object(里面有操作和属性)--dao 没有疑问了。这样的缺点我说说: 1.domain object和dao形成了双向依赖,复杂的双向依赖有可能产生很多潜在的问题。 2.你这样做会让大家产生很在的误会,导致整个结构的混乱无序。这个是service呢还是domain object呢? 3、service层必须对所有的domain object的业务逻辑提供相应的事务封装方法,太重复了,看着就不爽。比如你service里肯定还有个和object类似的方法transfer。何必多此一举。直接贫血不就行了,这样pojo还简单些。 我的结论,你何必一定要这种充血oo方式,难道就为了完全的oo?java里贫血不挺好的嘛,大家都这么用。 |
|
返回顶楼 | |
发表时间:2011-01-13
76052186 写道 很乱,不知道这说啥。
说我的看法,楼主的意思是想问,框架怎么才能与业务模型相互OO. 1:没有哪个软件是完全OO的,总有一些不是。比如Service在于给业务模型发消息时。保存数据到数据库时。 2:借助spring,hiberante等框架没办法很好的实现充血模型,这个讨论很久了。 楼主一直没把问题说清楚。我和gdpglc讨论就好了,不管他了。哈哈。 |
|
返回顶楼 | |
发表时间:2011-01-13
那问题不就明白了:
实际上SSH里的业务逻缉表达是面向过程的,也就是贫血。 到于 充血 vs 贫血 的问题,我也还是小学生,暂不发表相关言论。 |
|
返回顶楼 | |
发表时间:2011-01-13
gdpglc 写道 TonyLian 写道 感觉我的问题是具体的,而老师的回答都是“太极”的。
而这么一个具体的问题不弄清楚,如何能练就“太极”!? 在SSH框架下,开发一个OA(先不上升到工作流)系统,如何OO的把,人员、事宜等都落实? 在UML工具中画的 类图 如何变为现实的代码?如果用工具直接生成代码,如何放到SSH当中去呢? 所谓让业务逻缉OO,我想就是充血模型。引用一下Robin的话: robin 写道 如果你用的是Spring,没啥说的,必须贫血,你想充血也充不起来; 如果你用的是RoR,也没啥说的,直接充血,你想贫血也未必贫得下来; 实际上,让业务逻缉OO,对于SSH是有困难的。 现在的项目在实现时,业务逻缉主要都是以面向过程的方式表达的。 而且,面向过程的表达方式,是有其优点的。最主要的就是很容易被大众接受和理解。我觉得你问的问题很好,我刚工作时,也一直纠结在这个问题上。后来终于明白,其实大家都在面向过程开发... 实际上,让业务逻缉OO,对于SSH是有困难的。 不是让业务逻辑OO,而是在实现业务逻辑的时候保持业务对象的OO 比如逻辑层写查询用户 会是***Mgr.queryUser(String userName,String passWord); 还是***Mgr.quertUser(User user); 现在的项目在实现时,业务逻缉主要都是以面向过程的方式表达的。 逻辑必然是过程,不是过程话的语言,能表达清楚吗? 很反感这样的方式...把request丢到Manager里 public ModelAndView queryHistory(HttpServletRequest request, HttpServletResponse response) throws Exception { HashMap<String,Object> returnMap = ***Manager.query***List(request); return new ModelAndView("ajax_***", returnMap); } |
|
返回顶楼 | |
发表时间:2011-01-13
最后修改:2011-01-13
gdpglc 写道 没人说一定要用。而且现在大部份人都没用。因为它难用,而且大部份人用的是Spring。
好处坏处看经典吧,我说不出新东西。 你这个例子,好象不明显,而且我也不太理解你的需求。我举个别的吧,比如转帐。 从 A帐户取transferNum到B。 以下代码,只表语意 面向过程的方式: //transaction begin Account a=AccountDao.find...... a.setBalance(a.getBalance-transferNum); AccountDao.save(a); Account b=AccountDao.find...... b.setBalance(b.getBalance+transferNum); 业务 AccountDao.save(b); 持久化 //transaction end 面向对象的方式: Account类提供如下方法: void transferTo(Accout a,transferNum){ this.balance-=transferNum; a.balance+=transferNum; } 然后Service 里这样用: //事务开始 Account a=获得Account Acconnt b=获得Account a.transferTo(b,50); //事务结束 混着写 Account 是个实体,本身的业务是由人给予它含义的,所以不建议放到属于自己的类里实现transferTo |
|
返回顶楼 | |
发表时间:2011-01-13
最后修改:2011-01-13
领域对象来自于领域,业务逻辑也来自领域。所以才有 Domain Driven Design的理论。
|
|
返回顶楼 | |
发表时间:2011-01-13
没看透的人对这些比较有兴趣吧。
|
|
返回顶楼 | |