您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > JAVA

Java程序员对领域驱动设计的思考与认知

时间:2020-07-19 10:20:25  来源:  作者:

本项目是基于小编的开发经验与心得,分享小编关于领域模型的理解, 个人愚见仅供参考,希望能为渴望进步的你提供帮助。如果你感到有用对你有帮助,请不要吝啬你的关注,求关注,求转发。
文章有三个议题,什么是领域模型,为什么需要领域模型设计,以及领域驱动的项目结构是什么样的?

Java程序员对领域驱动设计的思考与认知

 

一、领域驱动模型是什么、领域驱动模型是什么?

一、

 一、领域驱动模型是什么?

如果你是第一次听到这个词,嗯,多么恐怖的一件事情呀! 什么是领域模型,一种新的技术吗? 领域模型到底有什么用呢?
为什么那么多大佬都在讲领域模型。网络上充斥着着各种高端的解释,各种高大上的名字,各种复杂的系统设计图。

Java程序员对领域驱动设计的思考与认知

 

fuck !身边总是有这样一群人的出现。总喜欢中文里夹杂英文,英文中夹杂着中文,仿佛这样能使他们更加自信一样。把你讲懵了,他就自信了。 very fuck !

身为技术人,尽量想把一种事情给讲清楚,说明白。而不是用各种抽象的晦涩难懂但看上去高大上的名词给解释。千万不要怕,下面我们通过先做一点小小的铺垫。最后在总结领域模型的理解。

1. 贫血模型

1. 贫血模型

1. 贫血模型

在讲清楚领域模型之前我们先来看引入一个词汇 “贫血模型” ,读到这里不要怕。只是一个词汇而已。是对我们平时的项目代码结构的一个形容词。相信无论面前的你
是一个大牛,还是一个刚入行的小菜鸟。你都一定写过这样的代码:

  • dao层: 负责持久化
  • model层: 数据模型
  • service层: 服务层
  • web层: 提供对UI层的访问

嗯。这就是一个典型的贫血模型, 哇,真的好形象,这是谁想出来的词汇,真想给他说一句 fuck you! 但是,但是,你还有更好的词汇来形容这种项目结构吗?
所谓贫血模型是指使用的领域对象中只有 `setter` 和 `getter` 方法(POJO),所有的业务逻辑都不包含在领域对象中而是放在业务逻辑层。
往往我们入行的初期我们都是在这样的项目结构中进行编程的,那个时候我们的业务往往都是简单的,对于那个时候的我们来说,这样的代码结构真是太好用了。清晰易懂。甚至想说一声 i love code !!!
这个时期,我们的关注点往往不是业务的复杂度,而是技术的使用,语法的使用。以及代码是否能编译通过。所以下面我们来总结一下贫血模型的优点。

2. 贫血模型优点

1. 被许多程序员所掌握,对于刚入行的同学来说,这种模型很自然很舒服,典型的MVC结构
2. 它非常简单,对于并不复杂的业务,它工作得很好,开发起来非常迅速。它似乎也不需要对领域的充分了解,只要给出要实现功能的每一个步骤,就能实现它。
3. 事务边界相当清楚,一般来说service的每个方法都可以看成一个事务。

3. 贫血模型缺点

随着发际线推移,随着历史的变迁,随着候鸟的迁徙。不知不觉我们的业务越来越复杂了。万恶的资本家,总想让我们一夜之间开发一个淘宝,一夜之间开发一个百度,一夜之间开发一个QQ。于是我们的service层,不断的
不断的增加。代码量从100行,200行,300行,10000行刹不住车了。终于小张忍不住了,辞职走了。留下了孤独的你独自承受这忧伤。

Java程序员对领域驱动设计的思考与认知

 

这样代码是什么意思? 这样代码能不能删?这行代码怎么没有走?这样代码能不能拆出去? 这样改万一项目上线崩溃了怎么办? 想一想老婆,望一望孩子。哎,算了吧。于是乎service复杂度指数般的递增。这就是贫血模型的缺点。

Java程序员对领域驱动设计的思考与认知

 

缺点

  1. 所有的业务都在service中处理,当业越来越复杂时,service会变得越来越庞大,最终难以理解和维护,轻则项目组解散,重则妻离子散。
  2. 将所有的业务放在无状态的service中实际上是一个过程化的设计,这与面向对象的编程风格,相向而行。(你转身离开分手说不出来,海鸟跟鱼相爱只是一场意外)
  3. 项目代码写的不少,重用的不多。(fuck and fuck = double kill)

4. 充血模

4. 充血模型

前面说我说了贫血模型,这里顺便提一下充血模型,也不要怕,也只是一个吓人的词汇。前面我们理解了贫血模型,那么充血模型,很容易就能理解。
前面我们说贫血模型实体类只有SET GET方法,逻辑基本在服务层实现。而充血模型它的实体类里不但有状态,还有行为,即属性和方法都有。它的Service层很薄。显然这不符合MVC的思想,因为充血模型中model中不仅有数据,还有状态。维护起来非常麻烦。

5. 领域驱动总结

针对贫血模型的service层非常复杂臃肿的缺点,领域模型的概念越来越流行起来,至少在一些很多的大公司中,非常盛行。领域模型的概念不仅可以重新去设计service,同时也在微服务设计中有重要的意义。所以说领域模型其实就是要解决service越来越臃肿的一种设计思想。主要就是对service中的复杂的业务逻辑进行拆分,根据领域来进行拆分。用面向对象的思想去重新设计service。有人给他起了一个高大上的词汇: 领域模型。

所以最后小编想用一大白话来总结一下领域模型。

领域模型就是要用面向对象的思想去重新设计充斥着复杂业务逻辑的service层。

二、为什么要进行领域模型设计?

相信看到这里的你,一定对领域模型有一个自己的认识。为什么要进行领域模型设计? 相信自己心里一定有一个自己的判断了。贫血模型的项目结构, service层无可避免的非常的臃肿,臃肿到一个方法可能深不见底。对于业务老油条,可能还凑合能看成,
假如你是一个新的同学,当你看到这样的代码一定是崩溃的,假如说注释也没有,那你内心更是崩溃的。假如说这是一个很庞大的系统,很复杂的业务流程,这就更不用说了。

Java程序员对领域驱动设计的思考与认知

 

如果读到这里,你还是对领域驱动设计感到迷茫,那么就其实这个标题也可以这样讲: 我们如何对臃肿的service进行面向对象的设计。设计的过程就是对service层的代码进行领域设计。
而我们之所以这样做的目的。

  1. 为了快乐的coding
  2. 为了业务系统的稳定
  3. 为了业务更快的迭代升级。

当然这一切的前提是你对业务有一个全局的认识,有一个前瞻性的判断,否则也设计不出来,真正适合自身系统的领域驱动模型。

三、领域驱动的项目结构是什么样的?

一千个人眼里有一千个哈姆雷特,没有最好的项目结构,只有最适合自己的业务系统。本文只是小编对领域驱动的模块的思考和认识。
仅供参考,希望对你有所启示和引导。

1. 领域划分|模块化建造

Java程序员对领域驱动设计的思考与认知

 

领域划分,小编感觉用另外一个词形容也非常的合适,就是业务模块化。所有能力都进行能力化抽象,形成模块,形成领域。 当遇到新的业务逻辑,底层的数据结构和数据关系肯定也是一样的。那么就可以像堆积木一样,根据这些模块快速的组装成新的业务逻辑。快速的实现业务的迭代和升级。
关于这个问题,需要结合自己的业务系统来进行抽象和设计。而小编的能做的就是,提醒你模块化设计,领域化设计的重要意义。

2. 项目结构

基础层(外部调用,db操作) + 领域层(偏向领域的业务逻辑) + 业务层(对领域层的业务编排) + 外观层(可以提供能力,可以提供视图)。
有一个完善的领域层,可以方便快速便捷的对业务进行扩展。

Java程序员对领域驱动设计的思考与认知

 

领域层就是模块化设计的积木。丰富的模块化有助于业务扩展。

一定要控制项目的依赖情况。service只能出现领域层的依赖, 领域层只能存在dao层和第三方服务层。各个层代码不能平行调用。

Java程序员对领域驱动设计的思考与认知

 

3. 编程规范

关于项目提出6个注意的点。如果把做项目比作是前线打仗,那么打仗最重要的是战斗成员目标要一致。在目标不一致的情况下一定要进行充分讨论(项目负责人要做的),说明情况互相妥协指定出统一的项目编程规范。去进行执行。一旦指定不能违背。否则项目质量不保。

项目固然重要,但是作为软件开发工程师,首先要对代码质量做保障。

Java程序员对领域驱动设计的思考与认知

 

4. 日志设计

天下没有完美的项目,任何系统不存在bug是不可能的。想要发现bug并快速定位问题,日志系统的不能缺少的。

日志系统是非常重要的系统, 对系统的监控, 在设计日志系统中,我们需要关注的点

  1. 日志结构(目的是按照结构解析到日志引擎中)
    如果想做日志的搜索平台,一定要进行日志结构化设计,方便被搜索平台的解析。如ELK日志搜索系统。
  2. 日志打印降级能力
    在遇到大促时候,可以减少不必要的日志打印,要对日志打印做降级的设计
  3. 异步输入日志
  4. 日志归档
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 系统日志打印 -->
    <Appender name="logfile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>${logger.logback.logpath}mbp-game-service.log</File>
        <encoder>
            <Pattern>[%date] [%-5level] %c{40} %line --%mdc{client} [%X{TRACE_LOG_ID}] [%X{dstTraceId}] %msg%n</Pattern>
            <charset>UTF-8</charset>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logger.logback.logpath}mbp-game-service.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <maxHistory>30</maxHistory>
            <TimeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>512MB</maxFileSize>
            </TimeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>

    <!-- 异步输出 -->
    <appender name="asyncAppender" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>1024</queueSize>
        <!-- 添加附加的appender,最多只能添加一个 -->
        <appender-ref ref="logfile"/>
    </appender>


    <!-- 外部jar包 日志级别设置 -->
    <logger level="${logger.outside.logLevel}" name="com.ibatis"/>
    <logger level="${logger.outside.logLevel}" name="org.springframework"/>
    <logger level="${logger.outside.logLevel}" name="JAVA.sql"/>
    <logger level="${logger.outside.logLevel}" name="org.Apache"/>
    <logger level="${logger.outside.logLevel}" name="com.alibaba.dubbo"/>
    <logger level="${logger.outside.logLevel}" name="org.I0Itec"/>
    <logger level="${logger.outside.logLevel}" name="org.dozer"/>
    <logger level="${logger.outside.logLevel}" name="kafka.producer.SyncProducer"/>
    <logger level="${logger.kafka.outside.logLevel}" name="org.apache.kafka"/>
    <logger level="${logger.kafka.outside.logLevel}" name="org.springframework.kafka"/>

    <!-- 输出到文件,可定义更多的 Appender -->
    <root level="${logger.logLevel}">
        <appender-ref ref="asyncAppender"/>
    </root>

</configuration>


Tags:Java程序员   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
从Java 10 开始,Java的迭代周期缩短为半年,半年发布一个版本。局部变量类型推断在Java 6时初始化一个Map需要我们这样来声明: Map<String, String> map = new HashMap<String,S...【详细内容】
2021-10-26  Tags: Java程序员  点击:(49)  评论:(0)  加入收藏
就业问题,是当下每个人都非常关注的问题,近年来的就业形势一直不是很好,就业就等于失业已经在多少人身上践行了,很多人面对就业就是一副被打击惆怅的面孔。Java程序员应该如何找...【详细内容】
2021-08-17  Tags: Java程序员  点击:(64)  评论:(0)  加入收藏
由于Java技术人才的稀缺,使得Java开发岗位的薪资很高,因此越来越多的人通过Java培训转行做Java开发,那么Java程序员每天的工作都是做什么的?有哪些是必须要做的?Java程序员每天...【详细内容】
2021-04-13  Tags: Java程序员  点击:(247)  评论:(0)  加入收藏
本文作者 : Stanley 罗昊本文转自: https://www.cnblogs.com/StanleyBlogs/p/14480990.html下载Layui与文件分析下载直接去官网下载即可 文件分析下载完成后,解压会得到一个文...【详细内容】
2021-03-09  Tags: Java程序员  点击:(220)  评论:(0)  加入收藏
好看的办公楼千篇一律,有趣的纬软人万里挑一!大家好,我是纬小创!作为优秀的打工人,拥有一些实用的工具,往往可以让工作效率翻倍提升。今天纬小创给大家介绍10款阿里Java程序员常用...【详细内容】
2020-12-16  Tags: Java程序员  点击:(94)  评论:(0)  加入收藏
好的工具做起事来常常事半功倍,下面介绍几个开发中常用到的工具类,收藏一下,也许后面真的会用到。 字符串处理:org.apache.commons.lang.StringUtilsisBlank(CharSequence) 可...【详细内容】
2020-08-12  Tags: Java程序员  点击:(57)  评论:(0)  加入收藏
本项目是基于小编的开发经验与心得,分享小编关于领域模型的理解, 个人愚见仅供参考,希望能为渴望进步的你提供帮助。如果你感到有用对你有帮助,请不要吝啬你的关注,求关注,...【详细内容】
2020-07-19  Tags: Java程序员  点击:(36)  评论:(0)  加入收藏
各位志同道合的朋友们大家好,我是一个一直在一线互联网踩坑十余年的编码爱好者,现在将我们的各种经验以及架构实战分享出来,如果大家喜欢,就关注我,一起将技术学深学透,我会每一篇...【详细内容】
2020-07-11  Tags: Java程序员  点击:(36)  评论:(0)  加入收藏
这篇文章主要来介绍下 JDK 内置的命令,话不多说,让我们开始吧!javap使用 javap 可以查看 Java 字节码反编译的源文件, javap 的命令格式如下: 下面来演示下用 javap -c 对代码进...【详细内容】
2020-05-14  Tags: Java程序员  点击:(49)  评论:(0)  加入收藏
从春节过后,我,一位双非渣本的大三学生,便踏上了实习之旅,面试了不下三十场,虽然很菜,但是也相应地拿了一些 offer ,例如京东金融、美团等五六家 offer总结一下春招就是一个字:难。...【详细内容】
2020-05-02  Tags: Java程序员  点击:(60)  评论:(0)  加入收藏
▌简易百科推荐
面向对象的特征之一封装 面向对象的特征之二继承 方法重写(override/overWrite) 方法的重载(overload)和重写(override)的区别: 面向对象特征之三:多态 Instanceof关键字...【详细内容】
2021-12-28  顶顶架构师    Tags:面向对象   点击:(2)  评论:(0)  加入收藏
一、Redis使用过程中一些小的注意点1、不要把Redis当成数据库来使用二、Arrays.asList常见失误需求:把数组转成list集合去处理。方法:Arrays.asList 或者 Java8的stream流式处...【详细内容】
2021-12-27  CF07    Tags:Java   点击:(3)  评论:(0)  加入收藏
文章目录 如何理解面向对象编程? JDK 和 JRE 有什么区别? 如何理解Java中封装,继承、多态特性? 如何理解Java中的字节码对象? 你是如何理解Java中的泛型的? 说说泛型应用...【详细内容】
2021-12-24  Java架构师之路    Tags:JAVA   点击:(5)  评论:(0)  加入收藏
大家好!我是老码农,一个喜欢技术、爱分享的同学,从今天开始和大家持续分享JVM调优方面的经验。JVM调优是个大话题,涉及的知识点很庞大 Java内存模型 垃圾回收机制 各种工具使用 ...【详细内容】
2021-12-23  小码匠和老码农    Tags:JVM调优   点击:(11)  评论:(0)  加入收藏
前言JDBC访问Postgresql的jsonb类型字段当然可以使用Postgresql jdbc驱动中提供的PGobject,但是这样在需要兼容多种数据库的系统开发中显得不那么通用,需要特殊处理。本文介绍...【详细内容】
2021-12-23  dingle    Tags:JDBC   点击:(13)  评论:(0)  加入收藏
Java与Lua相互调用案例比较少,因此项目使用需要做详细的性能测试,本内容只做粗略测试。目前已完成初版Lua-Java调用框架开发,后期有时间准备把框架进行抽象,并开源出来,感兴趣的...【详细内容】
2021-12-23  JAVA小白    Tags:Java   点击:(11)  评论:(0)  加入收藏
Java从版本5开始,在 java.util.concurrent.locks包内给我们提供了除了synchronized关键字以外的几个新的锁功能的实现,ReentrantLock就是其中的一个。但是这并不意味着我们可...【详细内容】
2021-12-17  小西学JAVA    Tags:JAVA并发   点击:(11)  评论:(0)  加入收藏
一、概述final是Java关键字中最常见之一,表示“最终的,不可更改”之意,在Java中也正是这个意思。有final修饰的内容,就会变得与众不同,它们会变成终极存在,其内容成为固定的存在。...【详细内容】
2021-12-15  唯一浩哥    Tags:Java基础   点击:(17)  评论:(0)  加入收藏
1、问题描述关于java中的日志管理logback,去年写过关于logback介绍的文章,这次项目中又优化了下,记录下,希望能帮到需要的朋友。2、解决方案这次其实是碰到了一个问题,一般的情况...【详细内容】
2021-12-15  软件老王    Tags:logback   点击:(19)  评论:(0)  加入收藏
本篇文章我们以AtomicInteger为例子,主要讲解下CAS(Compare And Swap)功能是如何在AtomicInteger中使用的,以及提供CAS功能的Unsafe对象。我们先从一个例子开始吧。假设现在我们...【详细内容】
2021-12-14  小西学JAVA    Tags:JAVA   点击:(21)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条