论坛首页 Java企业应用论坛

我与OO老师的问答(SSH与OO可以兼得吗),邀你继续...

浏览 29264 次
精华帖 (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.保存账户
0 请登录后投票
   发表时间: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);
//事务结束




0 请登录后投票
   发表时间:2011-01-13  
很乱,不知道这说啥。
说我的看法,楼主的意思是想问,框架怎么才能与业务模型相互OO.

1:没有哪个软件是完全OO的,总有一些不是。比如Service在于给业务模型发消息时。保存数据到数据库时。
2:借助spring,hiberante等框架没办法很好的实现充血模型,这个讨论很久了。
0 请登录后投票
   发表时间: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里贫血不挺好的嘛,大家都这么用。
0 请登录后投票
   发表时间:2011-01-13  
76052186 写道
很乱,不知道这说啥。
说我的看法,楼主的意思是想问,框架怎么才能与业务模型相互OO.

1:没有哪个软件是完全OO的,总有一些不是。比如Service在于给业务模型发消息时。保存数据到数据库时。
2:借助spring,hiberante等框架没办法很好的实现充血模型,这个讨论很久了。

楼主一直没把问题说清楚。我和gdpglc讨论就好了,不管他了。哈哈。
0 请登录后投票
   发表时间:2011-01-13  
那问题不就明白了:

实际上SSH里的业务逻缉表达是面向过程的,也就是贫血。

到于 充血 vs 贫血 的问题,我也还是小学生,暂不发表相关言论。
0 请登录后投票
   发表时间: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);
	} 


0 请登录后投票
   发表时间: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
0 请登录后投票
   发表时间:2011-01-13   最后修改:2011-01-13
领域对象来自于领域,业务逻辑也来自领域。所以才有 Domain Driven Design的理论。
0 请登录后投票
   发表时间:2011-01-13  
没看透的人对这些比较有兴趣吧。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics