AOSD:应用AOP实现业务逻辑

原创 2006年06月15日 20:57:00
(同步自http://www.blogjava.net/AndersLin/archive/2006/06/15/53079.html
(下面是发在javaeye上的帖子,因为觉的还有点意思,转到blog来,关于Domain和AOSD已经有了一些新的想法)

应用Domain开发的系统,通常把逻辑放在Domain Service层中,而Domain Service做两个工作:
1. 和表现层通信,表现为把表现层的平面数据(VO)转换为相关联的Domain对象,把Domain对象计算的结果转换成平面数据(VO)返回给表现层;
2.根据Use Case完成商业逻辑的调度。

以下主要讨论Use Case的内容。
通常Use Case所描述的Business Flow分为四种:Basic Flow,Alternate Flow,Exception Flow和Extension Flow。
虽然Business Flow可能包含很多领域对象,由于每个use case的目标带有浓厚的领域逻辑,因而可以通过分析提炼出一个主domain对象。然后重组转换来自BA或者PM的BP设计文档,使其中的Basic Flow基于主domain对象,而把 Alternate Flow,Exception Flow和 Extension Flow基于其它的Domain Service和Domain Object(当然包括Util objects), 最后利用AOP把Alternate Flow, Exception Flow和Extension Flow 与Basic Flow在Service层组织起来。
使用AOP来组织Use Case时,与使用AOP组织技术问题(比如日志,权限检查和事务处理等)不同。
在AOP组织技术问题时,我们不关心join point的目标对象和目标方法以及入口参数。比如:
 


事实用User Case的观点分析,发送短信通知是另一个use case,是转帐这个use case的extend flow。用AOP的方法应该如下:

这样我们完成了两个用例的分离,两个用例独立,可以重用和测试。比如上述短信通知用例其实可以被重用到其它情况如:存款,消费,以及银行分红等等。
不过可能面临一个情况是,两个独立用例的代码部分都可能用到某个对象, 那么在两个用例中可能重复一部分代码。虽然从概念上看,不应该重复(在使用用旧的方法实现时不会重复),但从不同use case看,这个重复是值得的。曾经考虑利用代码生成,直接获得Local Variable,这样可以减少重复,但是这个想法是错误的,不仅仅是实现上的困难,更重要在于,分离出的发送短信用例便绑定了转帐用例,依赖于转帐用例,而无法独立重用和测试。
这样,对象、方法以及方法参数构成了一个完整的pointcut,成为不同用例切片的共同入口,相当于一个占位符。这个时候就需要不同的用例实现人员协调好该入口。
public class BankServiceImpl implements BankService
public void transfer(UserAccount src, UserAccount dist, 
BigDecimal amount)
throws Exception
        src.subtract(amount); 
        dist.add(amount); 
}
 
//Other code goes here 
}
 

< bean id = "  BankService "   class = " org. 
springframework.transaction.interceptor.TransactionProxyFactoryBean "
     < property name = " transactionAttributes " >  
         
< props >  
< prop key = " transfer " > PROPAGATION_REQUIRED </ prop >                   
         
</ props >  
    
</ property >  
</ bean >  


我们不关心参数,或者在一些方法重载的地方利用参数来识别区分我们的方法入口。
但当我们利用AOP来组织Use Case时我们关心目标对象和目标方法以及入口参数因为AOP所要织入的方法是另一个Use Case是另一个Biz Flow。(这个在AOSD中显示讨论的不多,只有在12章12.4.中有提到)
比如我们要在转帐成功后发手机短信通知客户。那么在没有用AOP代码中我们这样写:

public class BankServiceImpl implements BankService
public void transfer(UserAccount src, UserAccount dist, 
BigDecimal change)
throws Exception
        src.subtract(change); 
        dist.add(change); 
        SMSService.sendSMS(src, change); 
        SMSService.sendSMS(dist, change); 
}
 
//Other code goes here 
}
 
Public 
class SMSService 
        
public static void sendSMS(UserAccount user, BigDecimal change)
             Long phone 
= user.getPhoneNumber(); 
             BigDecimal balance 
= user.getBalance(); 
             send(phone, change, belance) 
}
 
private static void send(Long phone, change, balance)
 
}
 
}
 

public class BankServiceEx 
public static void notify(UserAccount src, BigDecimal change) 
        SMSService.sendSMS(src, change); 
}
 
//Other code goes here 
}
 


public aspect BankServiceAspect 
pointcut transfer():call(
void BankService.transfer(..)); 
        
        after(UserAccount src, UserAccount dist, BigDecimal change) returning : transfer() 
&& args(src, dist, change)
        BankServiceEx.notify(src, change); 
BankServiceEx.notify(dist, change); 
        }
 
}
 


相关文章推荐

NET 应用架构指导 V2 学习笔记(十一) 业务逻辑层指导

业务逻辑层简介   上图的粗黑色边框的部分就是业务逻辑层,可以包含下面的内容:    application facade应用外观。这个可选的组件为业务逻辑组件提供一个简单的接口,通常会将多个业务...

086集-实现业务逻辑层

  • 2015年10月29日 12:21
  • 50.7MB
  • 下载

从存储过程说起,浅析业务逻辑写在数据库中还是应用程序中

从存储过程说起

分层架构与业务逻辑实现方式

  • 2012年12月11日 15:12
  • 118KB
  • 下载

系统架构师谈企业应用架构之业务逻辑层

一、上章回顾 上章我们主要讲述了系统设计规范与原则中的具体原则与规范及如何实现满足规范的设计,我们也讲述了通过分离功能点的方式来实现,而在软件开发过程中的具体实现方式简单的分为面向过程与面向对象...

在 Laravel 5 中使用 Repository 模式实现业务逻辑和数据访问的分离

1、概述 首先需要声明的是设计模式和使用的框架以及语言是无关的,关键是要理解设计模式背后的原则,这样才能不管你用的是什么技术,都能够在实践中实现相应的设计模式。 按照最初提出者的介绍,Re...

(5)业务逻辑的实现:数据如何处理

五、业务逻辑的实现:数据如何处理 重点是数据如何处理:Riak Core提供了一个统一的接口以控制分布在ring上的数据的计算(操作)。 Riak Core的数据控制接口 如前所述,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:AOSD:应用AOP实现业务逻辑
举报原因:
原因补充:

(最多只允许输入30个字)