一、贫血模型和充血模型
1.1、贫血模型
定义:领域对象里只有get,set方法,所有的业务逻辑都不包含在内,而是放到Business Logic层
优点:
- 各层单向依赖,结构清楚,易于实现和维护。
- 设计简单,底层模型非常稳定。
缺点:
- 领域层domain object部分比较紧密依赖持久化domain logic被分离到Service层,显得不够OO。
- Service过重。
样例:三层架构 。三层架构业务中经常使用基于贫血模式的开发模式。
Repository + Entity
Service + BO(Business Object)
Controller + VO(View Object)
代码:
1 /** 2 * 账户业务对象 3 */ 4 public class AccountBO { 5 6 /** 7 * 账户ID 8 */ 9 private String accountId; 10 11 /** 12 * 账户余额 13 */ 14 private Long balance; 15 /** 16 * 是否冻结 17 */ 18 private boolean isFrozen; 19 20 public String getAccountId() { 21 return accountId; 22 } 23 24 public void setAccountId(String accountId) { 25 this.accountId = accountId; 26 } 27 28 public Long getBalance() { 29 return balance; 30 } 31 32 public void setBalance(Long balance) { 33 this.balance = balance; 34 } 35 36 public boolean isFrozen() { 37 return isFrozen; 38 } 39 40 public void setFrozen(boolean isFrozen) { 41 this.isFrozen = isFrozen; 42 } 43 } 44 45 /** 46 * 转账业务服务实现 47 */ 48 @Service 49 public class TransferServiceImpl implements TransferService { 50 51 @Autowired 52 private AccountService accountService; 53 54 @Override 55 public boolean transfer(String fromAccountId, String toAccountId, Long amount) { 56 AccountBO fromAccount = accountService.getAccountById(fromAccountId); 57 AccountBO toAccount = accountService.getAccountById(toAccountId); 58 59 /** 检查转出账户 **/ 60 if (fromAccount.isFrozen()) { 61 throw new MyBizException(ErrorCodeBiz.ACCOUNT_FROZEN); 62 } 63 if (fromAccount.getBalance() < amount) { 64 throw new MyBizException(ErrorCodeBiz.INSUFFICIENT_BALANCE); 65 } 66 fromAccount.setBalance(fromAccount.getBalance() - amount); 67 68 /** 检查转入账户 **/ 69 if (toAccount.isFrozen()) { 70 throw new MyBizException(ErrorCodeBiz.ACCOUNT_FROZEN); 71 } 72 toAccount.setBalance(toAccount.getBalance() + amount); 73 74 /** 更新数据库 **/ 75 accountService.updateAccount(fromAccount); 76 accountService.updateAccount(toAccount); 77 return Boolean.TRUE; 78 } 79 }View Code
1.2、充血模型
定义:数据和对应的业务逻辑被封装到同一个类中。因此充血模型满足OOP。
优点:
- 面对对象,Business Logic复核单一职责,不想在贫血模型里面那样包含所有业务逻辑,太过于沉重。
缺点:
- 逻辑比较含糊。什么样的逻辑应该放到Domain Object中,什么样的业务逻辑应该放到Business Logic中。
切分原则:可重用度高的,和demain object状态密切关联的放到Domain Object中,可重用度低的,和domain object状态没有密切关联的放到Business Logic中。即domain logic只应该和这一个domain object的实例状态有关,而不应该和一批domain object的状态有关。
代码:
/** * 账户业务对象 */ public class AccountBO { /** * 账户ID */ private String accountId; /** * 账户余额 */ private Long balance; /** * 是否冻结 */ private boolean isFrozen; /** * 出借策略 */ private DebitPolicy debitPolicy; /** * 入账策略 */ private CreditPolicy creditPolicy; /** * 出借方法 * * @param amount 金额 */ public void debit(Long amount) { debitPolicy.preDebit(this, amount); this.balance -= amount; debitPolicy.afterDebit(this, amount); } /** * 转入方法 * * @param amount 金额 */ public void credit(Long amount) { creditPolicy.preCredit(this, amount); this.balance += amount; creditPolicy.afterCredit(this, amount); } public boolean isFrozen() { return isFrozen; } public void setFrozen(boolean isFrozen) { this.isFrozen = isFrozen; } public String getAccountId() { return accountId; } public void setAccountId(String accountId) { this.accountId = accountId; } public Long getBalance() { return balance; } /** * BO和DO转换必须加set方法这是一种权衡 */ public void setBalance(Long balance) { this.balance = balance; } public DebitPolicy getDebitPolicy() { return debitPolicy; } public void setDebitPolicy(DebitPolicy debitPolicy) { this.debitPolicy = debitPolicy; } public CreditPolicy getCreditPolicy() { return creditPolicy; } public void setCreditPolicy(CreditPolicy creditPolicy) { this.creditPolicy = creditPolicy; } } /** * 入账策略实现 */ @Service public class CreditPolicyImpl implements CreditPolicy { @Override public void preCredit(AccountBO account, Long amount) { if (account.isFrozen()) { throw new MyBizException(ErrorCodeBiz.ACCOUNT_FROZEN); } } @Override public void afterCredit(AccountBO account, Long amount) { System.out.println("afterCredit"); } } /** * 出借策略实现 */ @Service public class DebitPolicyImpl implements DebitPolicy { @Override public void preDebit(AccountBO account, Long amount) { if (account.isFrozen()) { throw new MyBizException(ErrorCodeBiz.ACCOUNT_FROZEN); } if (account.getBalance() < amount) { throw new MyBizException(ErrorCodeBiz.INSUFFICIENT_BALANCE); } } @Override public void afterDebit(AccountBO account, Long amount) { System.out.println("afterDebit"); } } /** * 转账业务服务实现 */ @Service public class TransferServiceImpl implements TransferService { @Resource private AccountService accountService; @Resource private CreditPolicy creditPolicy; @Resource private DebitPolicy debitPolicy; @Override public boolean transfer(String fromAccountId, String toAccountId, Long amount) { AccountBO fromAccount = accountService.getAccountById(fromAccountId); AccountBO toAccount = accountService.getAccountById(toAccountId); fromAccount.setDebitPolicy(debitPolicy); toAccount.setCreditPolicy(creditPolicy); fromAccount.debit(amount); toAccount.credit(amount); accountService.updateAccount(fromAccount); accountService.updateAccount(toAccount); return Boolean.TRUE; } }View Code
1.3、总结
贫血模型在传统开发模式更受欢迎。充血模型用于更加复杂的业务系统,更具优势。
标签:void,isFrozen,private,amount,Long,设计,驱动,public,DDD From: https://www.cnblogs.com/xiaobaicai12138/p/18053432