应用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的目标对象和目标方法以及入口参数。比如:
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/1fa987a29c6482f53d401256f96355eb.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/ca75c07623e1b494fee67e8f316fc310.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/9b8a8a44dd1c74ae49c20a7cd451974e.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/97e794c86028c5f5b5461ae5ef440a4c.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/3c6cafce68eb941a00f1998f1d3d3aa6.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/9b8a8a44dd1c74ae49c20a7cd451974e.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/ecedf933ec37d714bd4c2545da43add2.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/9b8a8a44dd1c74ae49c20a7cd451974e.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/8f1ba5b45633e9678d1db480c16cae3f.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/4f1150b881333f12a311ae9ef34da474.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/4f1150b881333f12a311ae9ef34da474.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/4f1150b881333f12a311ae9ef34da474.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/4f1150b881333f12a311ae9ef34da474.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/4f1150b881333f12a311ae9ef34da474.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/4f1150b881333f12a311ae9ef34da474.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/4f1150b881333f12a311ae9ef34da474.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/4f1150b881333f12a311ae9ef34da474.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/4f1150b881333f12a311ae9ef34da474.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/4f1150b881333f12a311ae9ef34da474.gif)
我们不关心参数,或者在一些方法重载的地方利用参数来识别区分我们的方法入口。
但当我们利用AOP来组织Use Case时我们关心目标对象和目标方法以及入口参数。因为AOP所要织入的方法是另一个Use Case是另一个Biz Flow。(这个在AOSD中显示讨论的不多,只有在12章12.4.中有提到)
比如我们要在转帐成功后发手机短信通知客户。那么在没有用AOP代码中我们这样写:
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/1fa987a29c6482f53d401256f96355eb.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/ca75c07623e1b494fee67e8f316fc310.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/9b8a8a44dd1c74ae49c20a7cd451974e.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/97e794c86028c5f5b5461ae5ef440a4c.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/3c6cafce68eb941a00f1998f1d3d3aa6.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/9b8a8a44dd1c74ae49c20a7cd451974e.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/ecedf933ec37d714bd4c2545da43add2.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/9b8a8a44dd1c74ae49c20a7cd451974e.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/8f1ba5b45633e9678d1db480c16cae3f.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/1fa987a29c6482f53d401256f96355eb.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/ca75c07623e1b494fee67e8f316fc310.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/9b8a8a44dd1c74ae49c20a7cd451974e.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/97e794c86028c5f5b5461ae5ef440a4c.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/3c6cafce68eb941a00f1998f1d3d3aa6.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/9b8a8a44dd1c74ae49c20a7cd451974e.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/ecedf933ec37d714bd4c2545da43add2.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/97e794c86028c5f5b5461ae5ef440a4c.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/3c6cafce68eb941a00f1998f1d3d3aa6.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/9b8a8a44dd1c74ae49c20a7cd451974e.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/9b8a8a44dd1c74ae49c20a7cd451974e.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/ecedf933ec37d714bd4c2545da43add2.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/8f1ba5b45633e9678d1db480c16cae3f.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/4f1150b881333f12a311ae9ef34da474.gif)
事实用User Case的观点分析,发送短信通知是另一个use case,是转帐这个use case的extend flow。用AOP的方法应该如下:
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/1fa987a29c6482f53d401256f96355eb.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/ca75c07623e1b494fee67e8f316fc310.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/9b8a8a44dd1c74ae49c20a7cd451974e.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/97e794c86028c5f5b5461ae5ef440a4c.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/3c6cafce68eb941a00f1998f1d3d3aa6.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/9b8a8a44dd1c74ae49c20a7cd451974e.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/ecedf933ec37d714bd4c2545da43add2.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/9b8a8a44dd1c74ae49c20a7cd451974e.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/8f1ba5b45633e9678d1db480c16cae3f.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/4f1150b881333f12a311ae9ef34da474.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/1fa987a29c6482f53d401256f96355eb.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/ca75c07623e1b494fee67e8f316fc310.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/9b8a8a44dd1c74ae49c20a7cd451974e.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/97e794c86028c5f5b5461ae5ef440a4c.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/3c6cafce68eb941a00f1998f1d3d3aa6.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/9b8a8a44dd1c74ae49c20a7cd451974e.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/d18c02628675d0a2c816449d98bda930.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/ecedf933ec37d714bd4c2545da43add2.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/8f1ba5b45633e9678d1db480c16cae3f.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/4f1150b881333f12a311ae9ef34da474.gif)
![点击在新窗口查看原始图片](https://i-blog.csdnimg.cn/blog_migrate/4f1150b881333f12a311ae9ef34da474.gif)
这样我们完成了两个用例的分离,两个用例独立,可以重用和测试。比如上述短信通知用例其实可以被重用到其它情况如:存款,消费,以及银行分红等等。
不过可能面临一个情况是,两个独立用例的代码部分都可能用到某个对象,那么在两个用例中可能重复一部分代码。虽然从概念上看,不应该重复(在使用用旧的方法实现时不会重复),但从不同use case看,这个重复是值得的。曾经考虑利用代码生成,直接获得Local Variable,这样可以减少重复,但是这个想法是错误的,不仅仅是实现上的困难,更重要在于,分离出的发送短信用例便绑定了转帐用例,依赖于转帐用例,而无法独立重用和测试。
这样,对象、方法以及方法参数构成了一个完整的pointcut,成为不同用例切片的共同入口,相当于一个占位符。这个时候就需要不同的用例实现人员协调好该入口。