当前位置: 首页 > 编程日记 > 正文

为什么这门技术如此重要?错过这次黄金期,就晚了!

老李一直怀疑自己是不是年纪大了,脑子跟不上了。

作为十几年经验的资深 Java 工程师,维护这公司产品的核心代码的他,现在迭代产品的时候,经常出 Bug 。

有时修复一个 Bug 时间,比开发一个需求的时间要长很多,这是常有的事儿,更可怕的是,改完一个 Bug ,又多出来几个 Bug,让人吐血不止。

这样的情况不在少数,近几次的更新都没有按原计划的时间完成,不但让 Leader 对老李的能力产生怀疑,也让他自己开始怀疑自己。

这是产品迭代到一定时期,必然出现的问题;还是自己年纪大了,在开发时各种问题没有考虑周全,多年的开发经验都不能支撑新的需求。

中年危机加上职业瓶颈,老王觉得自己应该回家修整一下状态了......

废话,改 Bug 的痛苦,每个人都经历过…...

不管是系统维护,还是是在现有系统中进行迭代开发的老司机们,这种痛苦经历,想必你们很熟悉吧:

当需要修改一个 Bug 的时候,面对一个类中成百上千行的代码,没有注释,千奇百怪的方法和变量名字,层层嵌套的方法调用,混乱不堪的结构,不要说准确找到 Bug 所在的位置,就是要清晰知道一段代码究竟是做了什么也非常困难,最终,改对了一个 Bug,却多冒出 N 个新 Bug;

同样的情况,当你拿到一份新的需求,需要在现有系统中添加功能的时候,面对一行行完全过程式的代码,需要使用一个功能时,不知道是应该自己编写,还是应该寻找是否已经存在的方法。

编写一个非常简单的新、删、改功能,却要费尽九牛二虎之力,最终发现,系统存在着太多的重复逻辑,阅读、测试、修改非常困难。

在经历了这些痛苦之后,我们都会发出一个感慨:MDZZ,与其进行系统维护和迭代开发,还不如重新设计开发一个新的系统来得痛快……

改不完的 Bug,是「思想错误」

当你遇到,你应该怎样解决?

面对这一系列让软件陷入无底泥潭的问题,基于面向对象思想的领域驱动设计方法是一个很好的解决方法。

从事过系统设计的富有经验的设计师们,对职责单一原则、信息专家、充血/贫血模型、模型驱动设计这些名词或概念应该不会感到陌生。

我们可以发现领域驱动设计的一大优点:系统高度模块化,代码重用度高,不会出现太多的重复逻辑。

从战略到战术,领域驱动设计(Domain Driven Design,DDD)给出了诸多关于软件架构、设计、建模与编码的方法和模式,以用于应对业务复杂度。

对于学习 DDD 的开发人员而言,第一重要的不是掌握 DDD 的模式,而是要改变分析思维与设计思维的方式。将这种思维方式运用到软件项目开发过程中,就是我所提到的「领域模型驱动设计」,它的核心内容可以通过层层推进的形式汇集为如下三句话:

  • 领域为分析建模的驱动力

  • 场景为设计建模的驱动力

  • 任务为实现建模的驱动力

如何理解这三句话?

当你开始领域模型驱动设计时,必须在分析建模阶段抛开实现技术对你的影响,与需求分析人员、测试人员一起单纯针对「领域」进行分析建模,即提炼与抽象领域概念,并以统一语言和模型的形式来表达。

在设计建模阶段,围绕着一个完整的「场景」开展设计工作。需求分析人员为「场景」编写用户故事;测试人员为「场景」编写验收标准;开发人员则开始解剖「场景」,将其分解为组合任务与原子任务,然后各自分配给不同的角色构造型。

到了实现建模阶段,就针对这些任务定义测试用例,开始测试驱动开发,由内至外到达应用服务时,再将它们集成起来。显然,领域模型驱动设计就是针对领域开展的「合而分分而合」的解构过程。

同时,必须谨记:领域模型驱动设计的基础是限界上下文。在领域驱动设计的战略阶段,同样是一个「合而分分而合」的解构过程:将领域分解为限界上下文,再通过上下文映射联合限界上下文共同实现多个领域场景。

以上内容正是我言犹未尽想要表达的精髓。学习领域驱动设计,就需要抓住 DDD 的根本和精髓。你需要理解什么是限界上下文,它带来的价值是什么;你需要理解如何进行领域建模,统一语言在其中扮演了什么样的角色;你需要理解为何领域驱动设计提倡以领域为驱动力,为何需要领域专家参与到项目开发中来。

提升了对这些内容的认识后,再去学习 DDD 给出的设计模式,学习我给出的固化设计过程,如场景驱动设计。然后找三两个不曾实施 DDD 的项目,寻两三个实施了 DDD 的项目,相互对比其模型与代码,你绝对会有一种醍醐灌顶的感觉。当然,这些都需要你沉下心来细心体会,认真思考,还需要你广泛涉猎更多软件设计与开发的知识,如此方能打通 DDD 的任督二脉

DDD 不是一门容易衰亡的软件方法学,反而越来越被行业所认可,薪资待遇也是水涨船高超过了大部分平均值。我从 2017 年 11 月写下本专栏的第一个字到现在完成整个专栏,已有两年多的时间了,好在 DDD 在这两年后依然算是一门显学,在微服务与中台光芒的映衬下,DDD 也变得越来越耀眼

这一路走来,读者们给了我莫大的鼓励。作为全网首个 DDD 专栏,已有超过  5000 位同学订阅学习了。大家每天都在群里进行各种交流分享,毕竟自己闷头学不如群策群力,一起给出解决方案更高效。

_

_

_

_

_

_

_

_

_

_

_

_

_

_

_

_

_

_

_

_

如今,专栏终于完成了!《战略篇》一共 34 章,15 万 5 千字;《战术篇》一共 71 章,35 万 1 千字;合计 105 章,共 50 万 6 千余字,加上两篇开篇词与这篇可以称为写后感的后记,共 108 章,算是凑齐了一百单八将。如此成果也足可慰藉我为之付出的两年多艰辛时光!

如果你想从此写代码再也碰不到 Bug

↓↓↓这门专栏非常适合你!↓↓↓

限时特价中

原价 168 元,限时立享 折!

↓下单再送 门万人订阅的编程课↓

118 元 = 108 章专栏➕7 门赠送编程课➕1V1 答疑➕源码

(迄今为止最划算的订阅时间)

现在订阅你能获得什么?

1. 专业老师陪伴式教学

张逸:曾就职于中兴、惠普、中软国际等公司的高级软件工程师

张逸老师将全程陪你一起吃透每章节内容,不再是你一人闷头去深究那些看不懂的知识点,让你能更高效快速的将所学的内容运用到工作项目中,让你的领导同事大吃一惊。

2. 360度全方位答疑服务

每个专栏都配有多个答疑交流群便于你们提问,老师几乎全程在线解答。群内还会有小助手负责日常整洁,让你在交流学习的同时不受到外界干扰。

3. 额外的福利

你不仅能以 7 折的优惠价格拥有战术➕战略 2 门合订版专栏,现在下单还将免费得到 7 门编程专栏。

如果你想从此写代码再也碰不到 Bug

↓↓↓这门专栏非常适合你!↓↓↓

限时特价中

原价 168 元,限时立享 折!

↓下单再送 门万人订阅的编程课↓

118 元 = 108 章专栏➕7 门赠送编程课➕1V1 答疑➕源码

(迄今为止最划算的订阅时间)


订阅须知

1. 怎样获取福利?

订阅专栏后可联系小助手「GitChatty6」,回复口令即可快速入群获得。

2. 如何阅读专栏?

本专栏可在 GitChat 服务号、App 及网页端上多端阅读。

3. 专栏内容有多少?

本专栏为图文内容,总共 108 篇课时。

4. 专栏有效期多久?

本专栏一经购买,即可享受永久阅读权限。


点击阅读原文,立即抢购!

相关文章:

字符编码简介 ANSI Unicode Unicode big endian UTF-8

1. ASCII码 我们知道,在计算机内部,所有的信息最终都表示为一个二进制的字符串。每一个二进制位(bit)有0和 1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte&#xff0…

ReactiveCocoa代码实践之-更多思考

三.ReactiveCocoa代码实践之-更多思考 1. RACObserve()宏形参写法的区别 之前写代码考虑过 RACObserve(self.timeLabel , text) 和 RACObserve(self , timeLabel.text) 的区别。 因为这两种方法都是观察self.timeLabel.text的属性,并且都能实现功能。估计是作者原本…

Java常用命令及Java Dump

线程Dump,包含所有线程的运行状态。纯文本格式。 堆Dump,包含线程Dump,幵包含所有堆对象的状态。二进制格式。 Java Dump方法 1.使用Java虚拟机制作Dump 指示虚拟机在发生内存不足错误时,自动生成堆Dump -XX:HeapDumpOnOutOfMemoryError 2.使用图形化工具制作Dump 使用JDK…

使用Windows远程登录Ubuntu

一、SSH登录 1、Ubuntu默认没有安装SSH ,可以在新得利软件安装程序里,搜索SSH,标记并安装; 或者使用命令: sudo apt-get install openssh-server sudo /etc/init.d/ssh restart ssh localhost…

紧急更新下降难度,《王者荣耀》绝悟 AI 难倒一片玩家

作者 | 神经星星来源 | HyperAI超神经(ID: HyperAI)在 5 月 1 日~ 5 月 4 日期间,玩家通过《王者荣耀》最新版本客户端进入游戏,即可与绝悟 AI 对战。一时间哀鸿遍野,普通玩家、游戏主播、职业选手,纷纷表示…

SQL:安装多个实例,修改实例端口号,和IP加端口号连接实例

原文:SQL:安装多个实例,修改实例端口号,和IP加端口号连接实例sql server 安装第一个实例,默认实例的端口是1433, 一个库中如果有多个实例,从第二个实例开始的端口是动态端口,需要的话,自己手工指…

用“逐步排除”的方法定位Java服务线上“系统性”故障

说明:原文地址已经不可访问,其他地方有转载,不过很多丢失图片,所以,找到一处有图的重新配好图。 用“逐步排除”的方法定位Java服务线上“系统性”故障 Posted on 2014/08/25李斯宁(高级测试开发工程师&…

清华硕士爆料:这些才是机器学习必备的数学基础

现如今,计算机科学、人工智能、数据科学已成为技术发展的主要推动力。无论是要翻阅这些领域的文章,还是要参与相关任务,你马上就会遇到一些拦路虎:想过滤垃圾邮件,不具备概率论中的贝叶斯思维恐怕不行;想试…

LINUX环境下资源下载中文目录及中文文件名称问题

为什么80%的码农都做不了架构师?>>> http://www.yeeach.com/2009/04/09/linux%E7%8E%AF%E5%A2%83%E4%B8%8B%E8%B5%84%E6%BA%90%E4%B8%8B%E8%BD%BD%E4%B8%AD%E6%96%87%E7%9B%AE%E5%BD%95%E5%8F%8A%E4%B8%AD%E6%96%87%E6%96%87%E4%BB%B6%E5%90%8D%E7%A7%B…

dojo从asp.net中获取json数据

搞来有搞去终于有了个结果,主要是一开始犯了一些低级错误。 对于json不太了解的童鞋,可以看看这个:http://www.dreamdu.com/blog/2008/10/19/json_in_javascript/ 这个例子中主要是从数据库中读取数据,转换成JSON格式,…

RHEL5 install

RHEL5 安装转载于:https://blog.51cto.com/bhanv/477708

线上java问题排查

0.jps 这个输出java进程pid #jps 查看java的线程 #top -Hp 25448 如图25757这个线程比较耗时,看看他在做什么 注意需要折算出线程pid的16进制值,然后jstack。 可以打印更多信息 #jstack pid | grep -A 20 649d 参考:JVM调优之jstack找出…

GitHub标星10,000+,Apache项目ShardingSphere的开源之路

【编者按】几天前,当 GitHub 全球产品技术生态总经理 Michael Francisco 谈到中国开发者已经成为 GitHub 上最活跃的群体时,有开发者提出数量之后质量也要跟上。的确,过去十数年间,中国开源一直呈现企业热使用热社区冷开发冷的景象…

JAVA中LOCK

原文链接:http://www.cnblogs.com/dolphin0520/p/3923167.html 一.synchronized的缺陷 我们知道如果一个代码块被synchronized修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的…

【公开课预告】AutoML知多少

5月7日周四19:00,商汤泰坦公开课第010期,论文解读系列课程第二期即将开播!我们邀请到商汤科技的4位研究员,分享团队在AutoML方面的一系列研究工作,其中包含CVPR 2020、ICLR 2020等多篇最新论文成果,想要了解…

Linux kernel futex.c的bug导致JVM不可用

JVM死锁导致线程不可用,然后会瞬间起N个线程,当然也是不可用的,因为需要的对象死锁,然后耗尽文件句柄导致外部TCP无法建议拒绝服务,jstack之后就会恢复。 解决办法:替换中间件类库 ,比如httpcli…

ruby爬虫综述

http://ihower.tw/blog/archives/2941一个ruby爬虫的例子http://hi.baidu.com/anspider/blog/item/9da210425a0e4e179213c6fb.html

Exchange 2016集成ADRMS系列-12:域内outlook 2010客户端测试

接下来,我们来到域内安装了office 2010的机器上进行测试。 首先我们在客户端上强制刷新组策略,把我们刚才设置的策略刷新下来。 然后我们可以运行gpresult /h result.html来看看策略是不是已经下来了。 策略下来之后,我们打开客户端上面的out…

在Linux下编写Daemon

在Linux下编写Daemon 转自:http://blog.163.com/prevBlogPerma.do?hostmanyhappy163&srl1644768312010718111142260&modeprev 在Linux(以Redhat Linux Enterprise Edition 5.3为例)下,有时需要编写Service。Service也是…

JVM虚拟机参数配置官方文档

JDK8 https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/index.html JDK7 https://docs.oracle.com/javase/7/docs/technotes/tools/solaris/java.html 官方博客 https://blogs.or…

在Rust代码中编写Python是种怎样的体验?

作者 | Mara Bos,Rust资深工程师译者 | Arvin,编辑 | 屠敏来源 | CSDN(ID:CSDNnews)大约一年前,我发布了一个名为inline-python(https://crates.io/crates/inline-python)的Rust类库…

Docker配置指南系列(二):指令集(二)

pause: 停止一个容器的所有进程语法:ocker pause CONTAINER [CONTAINER...] port: 列出容器的端口映射,或者查看指定开放端口的NAT映射语法:docker port [--help] CONTAINER [PRIVATE_PORT[/PROTO]] ps: 列出容器语法&#xff1…

无需训练RNN或生成模型,我写了一个AI来讲故事

作者 | Andre Ye译者 | 弯月出品 | AI科技大本营(ID:rgznai100)这段日子里,我们都被隔离了,就特别想听故事。然而,我们并非对所有故事都感兴趣,有些人喜欢浪漫的故事,他们肯定不喜欢…

Java字节码instrument研究

MyAgent项目 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.…

怎样保持良好的心态

有一位朋友有一次气冲冲的跟我说&#xff1a;“气死我了&#xff01;我刚刚发现我一位员工出了错&#xff0c;令产品出现了质量的问题&#xff0c;我修理了他一顿。。。 我问&#xff1a;”你认为你的生产流程里面可能一点错误都没有吗&#xff1f;“ 他说&#xff1a;”应该不…

web编程速度大比拼(nodejs go python)(非专业对比)

C10K问题的解决&#xff0c;涌现出一大批新框架&#xff0c;或者新语言&#xff0c;那么问题来了:到底谁最快呢&#xff1f;非专业程序猿来个非专业对比。 比较程序&#xff1a;输出Hello World&#xff01; 测试程序&#xff1a;siege –c 100 –r 100 –b 例子包括&#xff1…

linux邮件服务

邮件服务要求:l 能够构建完整的邮件系统 能够正确设置DNS邮件服务器记录 l 能够配置sendmail服务器 设置客户端软件使用邮件服务器 准备工作&#xff1a; l 主机名&#xff1a;srv.benet.com /etc/sysconfig/network <永久的> l 域名 正向区域 bt.com完成NDS的…

MaskFlownet:基于可学习遮挡掩模的非对称特征匹配丨CVPR 2020

来源 | 微软研究院AI头条&#xff08;ID: MSRAsia&#xff09;编者按&#xff1a;在光流预测任务中&#xff0c;形变带来的歧义与无效信息会干扰特征匹配的结果。在这篇 CVPR 2020 Oral 论文中&#xff0c;微软亚洲研究院提出了一种可学习遮挡掩模的非对称特征匹配模块 &#x…

GDB调试--以汇编语言为例

#rpm -qa |grep gdb 下载&#xff1a; 安装 #tar -zxvf #./configure #make 使用GDB 以汇编语言调试为例 汇编语言实现CPUID指令 CPUID cpuid是Intel Pentinum以上级CPU内置的一个指令&#xff08;486级以下的CPU不支持&#xff09;&#xff0c;他用于识别某一类型…

汇编语言系统调用过程

以printf为例&#xff0c;详细解析一个简单的printf调用里头&#xff0c;系统究竟做了什么&#xff0c;各寄存器究竟如何变化。 如何在汇编调用glibc的函数&#xff1f;其实也很简单&#xff0c;根据c convention call的规则&#xff0c;参数反向压栈&#xff0c;call&#xf…