精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2004-10-30
我现在对domain model的理解是这样的,对于通用的业务逻辑,应该写到domain object中,而对于非通用的业务逻辑应该写到domain logic中,现在举个简单的例子: 一个银行账号的例子(Account),这个Account毫无疑问应该作为domain object 出现,而且一般也不需要继承任何东西,一般来说对于一个银行账号,deposit(存款),withdraw(取款),transfer(转帐)等操作,我想够通用了吧,所以我现在设计过程中把这些操作放到了Account这个pojo中,而且这也符合OO的编程思维,而对于insertAccount操作放到AccountService中,我现在使用的spring声明式事务操作,target我指向的是AccountService,这样对于AccountService中的操作可以使用事务处理,但此时deposit(存款),withdraw(取款),transfer(转帐)等操作如何才可以享受事务处理呢? 难道需要把target也指向Account吗?但是target似乎只能指向一个吧?对与这点我甚感疑惑,还是我domain model的设计有问题? 看部分代码: pojo的代码,很简单,很多东西没包含在内,比如RuntimeException的处理 引用 public class Account
{ private String id; private String accountname; private String passwd; private String gender; private String email; private int amount; //业务逻辑 public int deposit(int amount) { return this.amount + amount; } public int withdraw(int amount) { return this.amount - amount; } public int transfer(int amount,String receiver) { this.amount = this.amount - amount; AccountService as = ... Account account2 = as.findByAccountname("receiver"); account2.deposit("amount"); as.updateAccount(account2); return this.amount; } public int checkleft() { return amount; } } domain logic代码: 引用 public interface AccountService
{ public void insertAccount(Account account); public Account findByAccountname(String accountname); public void updateAccount(Account account); } 现在只有AccountService里的代码可以享受事务,但是Account里的业务逻辑如何享受事务呢?用domain model应该如何设计呢? 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2004-10-30
我不知道你为什么要把它想得那么复杂。你只要确定在什么地方划定用例边界就行了。如果你认为WebWork action是用例边界,那么用WebWork interceptor来管理事务;如果你认为business facade是用例边界,那么给facade加一个dynamic proxy管理事务。就这么简单的一件事。至于domain object还是transaction script,那完全是你的实现细节,跟facade以上的东西没关系。
|
|
返回顶楼 | |
发表时间:2004-10-30
gigix 写道 我不知道你为什么要把它想得那么复杂。你只要确定在什么地方划定用例边界就行了。如果你认为WebWork action是用例边界,那么用WebWork interceptor来管理事务;如果你认为business facade是用例边界,那么给facade加一个dynamic proxy管理事务。就这么简单的一件事。至于domain object还是transaction script,那完全是你的实现细节,跟facade以上的东西没关系。
怎么能说与domain object还是transaction script实现没有关系呢?如果用Transaction script的话,那么我所有的业务逻辑可能全在service里面,这样的话,我可以用dynamic proxy或是spring的声明式事务出来(其实原理一样),也就是说我在webwork层的话就不需要考虑事务处理了,这样的事务处理全部不用我们用代码显示处理了,而如果是domain model的话,domain中包含有业务逻辑,而这部分业务逻辑应该如何处理事务,按照你的思路的话,就是webwork层用interceptor来管理事务,因为就上面的例子来说,无论是withdraw 还是transfer都应该是得到Account后在webwork层来调用的,所以这部分事务只能由interceptor来处理,OK,这样可以实现事务处理,但是毕竟还是要我们手写代码来实现事务,这样就失去了事务作为infrastructure的意义。再在EJB中来看这个例子,如果domain中的业务逻辑也在客户端来处理的话,那不是还要lookup transaction吗?那如何交由Container来处理事务呢?我想这仍是个问题 |
|
返回顶楼 | |
发表时间:2004-10-30
引用 现在只有AccountService里的代码可以享受事务,但是Account里的业务逻辑如何享受事务呢?用domain model应该如何设计呢? 把通用的逻辑放入domain model是合理的,在domain上不用实现事务,而是在在service上来提供事务功能,我 现在就是这样做的,通过动态代理,threadlocal来实现事务管理,事务自然在model中传播;如果直接把domain传到表示层,那么domain object的逻辑是没有事务的,那么必须规定:domain object 不能做vo穿到表示层;或者在表示层只通过service层调用业务逻辑; 后者是比较合理得,应为通常facade层来界定用例是比较合理得,web层得action就应该做得很薄,不实现或者几乎不实现业务逻辑,这样就没有理由需要事务了 |
|
返回顶楼 | |
发表时间:2004-10-30
Jolin 写道 引用 现在只有AccountService里的代码可以享受事务,但是Account里的业务逻辑如何享受事务呢?用domain model应该如何设计呢? 把通用的逻辑放入domain model是合理的,在domain上不用实现事务,而是在在service上来提供事务功能,我 现在就是这样做的,通过动态代理,threadlocal来实现事务管理,事务自然在model中传播;如果直接把domain传到表示层,那么domain object的逻辑是没有事务的,那么必须规定:domain object 不能做vo穿到表示层;或者在表示层只通过service层调用业务逻辑; 后者是比较合理得,应为通常facade层来界定用例是比较合理得,web层得action就应该做得很薄,不实现或者几乎不实现业务逻辑,这样就没有理由需要事务了 只在service上提供事务处理,如何在model中传播?现在我也只是在service上提供事务处理,所以service上的方法都可以享受事务,没问题。web层我是这样写的: 引用 AccountService as = ...
Account account = as.findByAccountname("hpq852"); account.deposit("10000"); as.updateAccount(account); 所以此时如果我只是做deposit 和 withdraw时候,可能没问题,因为整个过程只是一个update。但如果我进行transfer操作的时候: 引用 AccountService as = ...
Account account = as.findByAccountname("hpq852"); account.transfer("10000","jolin");//此时transfer由于也是调用service上的方法,所以同样享受事务处理 as.updateAccount(account); 如果是这样的话,问题来了,转帐的操作必须原子性,也就是说transfer的事务应该和as.updateAccount(account);的事务是同一个才可以保证正确,而此时两个事务是分开的,所以此时应该如何处理呢?难道还需要在web层调用interceptor在开一个事务?把两个方法包在一起? |
|
返回顶楼 | |
发表时间:2004-10-30
引用 AccountService as = ...
Account account = as.findByAccountname("hpq852"); account.deposit("10000"); as.updateAccount(account); web层不应该跨过service直接去调用donmain层的东西 引用 AccountService as = ...
Account account = as.findByAccountname("hpq852"); account.transfer("10000","jolin");//此时transfer由于也是调用service上的方法,所以同样享受事务处理 as.updateAccount(account); 怎么能让transerfer 去调用上一层service层的的东西呢? 引用 如果是这样的话,问题来了,转帐的操作必须原子性,也就是说transfer的事务应该和as.updateAccount(account);的事务是同一个才可以保证正确,而此时两个事务是分开的,所以此时应该如何处理呢?难道还需要在web层调用interceptor在开一个事务?把两个方法包在一起? 既然transfer是事物的,为什么不把转帐业务在一个service方法 提供呢?web中的action中是不该出现下面的代码 Account account = as.findByAccountname("hpq852"); account.transfer("10000","jolin");//此时transfer由于也是调用service上的方法,所以同样享受事务处理 as.updateAccount(account) |
|
返回顶楼 | |
发表时间:2004-10-30
我上面的那个例子如果要是挑毛病,恐怕无数,我只是为了想了解一下domain model到底应该如何设计。
jolin 写道 既然transfer是事物的,为什么不把转帐业务在一个service方法 提供呢?web中的action中是不该出现下面的代码
Account account = as.findByAccountname("hpq852"); account.transfer("10000","jolin");//此时transfer由于也是调用service上的方法,所以同样享受事务处理 as.updateAccount(account) 如果我把transfer,withdraw,deposit等方法都放到service里面的话,那不是又回到了transaction script了吗?我就是不想使用ts才这样来做的。transfer这个业务逻辑够通用了吧,所以我才放到domain object里。 jolin 写道 web层不应该跨过service直接去调用donmain层的东西
web层不能直接调用domain层的东西吗?那domain object怎么传到web层呢?难道还需要加一层dto?而且domain上的业务逻辑应该如何调用呢?由谁来调用呢? |
|
返回顶楼 | |
发表时间:2004-11-10
Hibernate的interceptor和spring:
http://forum.springframework.org/viewtopic.php?t=301&postdays=0&postorder=asc&start=0 |
|
返回顶楼 | |
发表时间:2004-11-11
我做法很极端。
1.每个business object对应一个表,不包含任何业务逻辑。 2.用hibernate做持久化,但不用它的任何关联关系。 3.DAO层只有一个类,继承spring的HibernateDAOSupport类,完成对数据库的所有操作。 4.业务逻辑全部写在Service层,调用DAO的那个类来处理数据库交互。 5.用spring的事务包装Service层。 丢失了很多OO的特性,但让我的工作变得简单了,你要不要考虑下? |
|
返回顶楼 | |
发表时间:2004-11-12
towjzhou 写道 我做法很极端。
1.每个business object对应一个表,不包含任何业务逻辑。 2.用hibernate做持久化,但不用它的任何关联关系。 3.DAO层只有一个类,继承spring的HibernateDAOSupport类,完成对数据库的所有操作。 4.业务逻辑全部写在Service层,调用DAO的那个类来处理数据库交互。 5.用spring的事务包装Service层。 丢失了很多OO的特性,但让我的工作变得简单了,你要不要考虑下? 呵呵,典型的Transaction Script做法。 |
|
返回顶楼 | |