java领域模型设计实例_Java开发架构篇:DDD模型领域层决
策规则树服务设计
⼀、前⾔
在上⼀章节介绍了领域驱动设计的基本概念以及按照领域驱动设计的思想进⾏代码分层,但是仅仅只是从⼀个简单的分层结构上依然没法理解DDD以及如何去开发这样的微服务。另外往往按照这样分层后依然感觉和MVC也没有什么差别,也没有感受到带来什么⾮常⼤的好处。那么问题出在哪呢?我个⼈觉得DDD学起来更像是⼀套指导思想,不断的将学习者引⼊到领域触发的思维中去,⽽这恰恰也是最难学习的地⽅。时⽽感觉会了,⽽实际开发中⼜不对,本来已经拆解清晰了,但怎么⼜那么像MVC了。甚⾄怀疑⾃⼰,我在⼲嘛?
⽆论是DDD、MVC,他们更像是家⾥三居或者四局的格局,每⼀种格局⽅式都是为了更好的实现对应架构下的设计思想。但,不是说给你⼀个通⽤的架构模式,你就能开发出⼲净(⾼内聚)、整洁(低耦合)、漂亮(模块化)的代码。这就像是你家住三居、他家也住三居,但是你们屋⼦的舒适情况就⼀样吗?{再有,你家⾥会把厕所安在厨房吗?但你的代码是否这么⼲过,不合理的摆放导致重构延期。}
另外DDD之所以看着简单但⼜不那么好落地,个⼈认为很重要就是领域思想,DDD只是指导但是不能把
互联⽹天下每⼀个业务⾏为开发都拿出来举例⼦给你看,每个领域需要设计。所以需要⼀些领域专家{产品+架构+不是杠精的程序员}来讨论梳理,将业务形态设计出合理的架构&代码。
⼆、案例⽬标
本案例通过⼀个商品下单规则的场景来进⾏演⽰DDD;
1. 假设产品需求业务运⾏⼈员可以对不同的商品配置⼀些规则,这些规则可以满⾜不同⽤户类型可以下单不同商品。
2. 另外⼀些⾏为规则是会随着业务发展⽽增加或者变动的,所以不能写死{写死太吓⼈了}。
3. 数据库的PO类不应该被外部服务调⽤,这也是必须的。如果你开发过很多系统,那么可能已经吃过亏并意识到这个问题。
4. 按照DDD思想我们尝试需要设计⼀个规则引擎的服务,通过给外部提供⾮常简单的接⼝(application)来获取最终结果。
5. 通过这样的案例可以很容易的感受到⽬前的四层架构确实在实现DDD思想上有很多的帮助。
>如图;DDD分层结构 | 指导设计架构
三、DDD思想 · 开发设计
通过领域驱动设计的思想,从领域知识中提取和划分为⼀个⼀个的⼦领域(核⼼⼦域,通⽤⼦域,⽀撑⼦域),并在⼦领域上建⽴模型。那么
在技术实现上就需要去⽀撑这种建模,以使我们的代码模块独⽴、免污染、易于扩展。
在上⾯我们提到需要开发⼀个可扩展使⽤的规则树,那么如果只是单纯的⼀次性需求,最快的⽅式是if语句就搞定了。但是为了使这个领域
服务具备良好的使⽤和扩展性,我们需要做些拆分,那么如下;
1、你是否想过系统在过滤过则的时候其实就像执⾏⼀棵⼆叉树⼀样⾮左即右侧,每⼀条线上都有着执⾏条件,通过判断来达到最终的结
java技术专家果。
2、按照树形结构我们将定义出来四个类;树、节点、果实、指向线(From-To),⽤于描述我们的规则⾏为。
3、在此基础上需要实现⼀个逻辑定义与规则树执⾏引擎,通过统⼀的引擎服务来执⾏我们每次配置好的规则树。
>如图;领域开发设计服务
四、⼯程模型
itstack-demo-ddd-02└── src ├── main │├── java ││└── org.itstack.demo ││├── application │││├── MallRuleService.java │││演⽰部分重点代码块,完整代码下载关注;bugstack⾍洞栈 | 回复DDD落地
application应⽤层
>application/MallRuleService.java | 应⽤层定义接⼝服务,也可以适当做简单包装
/** * 商超规则过滤服务;提供规则树决策功能 * :bugstack⾍洞栈 | 专注原创技术专题案例 * 论坛:bugstack * Create by ⼩傅哥 on @2019 */pub
domain领域层
domain中有两个领域服务;规则树信息领域、规则执⾏领域,通过合理的抽象化来实现⾼内聚、低耦合的模块化服务
>domain/service/MallRuleServiceImpl.java | 领域层中的service来实现应⽤层接⼝
/
** * 规则树服务;提供规则规律功能 * * 1、rule包下只进⾏规则决策领域的处理 * 2、封装决策⾏为到领域模型中,外部只需要调⽤和处理结果即可 * 3、可以扩展不同>domain/service/logic/LogicFilter.java | 逻辑决策定义
/** * :bugstack⾍洞栈 | 专注原创技术专题案例 * 论坛:bugstack * Create by ⼩傅哥 on @2019 */public interface LogicFilter { /** * 逻辑决策>domain/service/engine/EngineFilter.java | 引擎执⾏定义
/** * :bugstack⾍洞栈 | 专注原创技术专题案例 * 论坛:bugstack * Create by ⼩傅哥 on @2019 */public interface EngineFilter { EngineResult
infrastructure基础层
1. 实现领域层仓储定义
2. 数据库操作为⾮业务属性的功能操作
3. 在仓储实现层进⾏组合装配DAO&Redis&Cache等
>infrastructure/repository/RuleRepository.java
/** * :bugstack⾍洞栈 | 专注原创技术专题案例 * 论坛:bugstack * Create by ⼩傅哥 on @2019 */public interface EngineFilter { EngineResult
interfaces接⼝层
1. 包装应⽤接⼝对外提供api
2. 外部传输对象采⽤DTO类,主要为了避免内部类被污染{不断的迭代的需求会在类中增加很多字段}
3. ⽬前依然是提供的Http服务,如果提供的rpc服务,将需要对外提供可引⽤jar
>interfaces/DDDController.java
** * :bugstack⾍洞栈 | 欢迎关注学习专题案例 * 论坛:bugstack * Create by ⼩傅哥 on @2019 */@Controllerpublic class DDDController { priv 五、测试验证
>规则树结构{数据库转Json} | 可⾃⾏定义
{ "treeNodeMap": { "1": { "nodeType": 1, "ruleDesc": "⽤户性别[男/⼥]", "ruleKey": "userGender", "treeId": 10001, "treeNod >通过postman调⽤ | raw => json
查询规则树信息
请求参数:{"treeId":10001}
{ "treeInfo": { "treeId": 10001, "treeName": "购物分类规则树", "treeDesc": "⽤于分类不同类型⽤户可购物范围", "nodeCount": 7, "lineCount":
规则树⾏为信息决策
请求参数:{"treeId":10001}
{ "userId": "fuzhengwei", "treeId": 10001, "nodeId": 112, "nodeValue": "果实B", "success": true}
服务端
. ____ _ __ _ _ / / ___'_ __ _ _(_)_ __ __ _ ( ( )___ | '_ | '_| | '_ / _` | / ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |___, | / / / / ==六、综上总结
**以上模拟购物场景下的规则处理抽象为树决策引擎,以达到独⽴领域服务。另外决策服务可以使⽤drools,任何抽象并不⼀定永远使⽤,不要拘泥于⼀种形式**
⼀些⼤型架构设计往往不是换⼀个设计模型就能彻底提升效率,还是需要⼈员整体素质,这是⼀个不断培养的过程
领域驱动设计的思想并不只是教会程序员写代码,也是⾮程序员以外的所有互联⽹⼈员都适合学习的内容
家⾥住的舒适不舒适,并不⼀定取决于三居或者四居,⼤部分还是依赖于怎么对格局的布置。事必躬亲、亲⼒亲为的精益求精之路,终究会让你设计出更加合理的代码
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论