暂时未有相关云产品技术能力~
暂无个人介绍
在DDD中Repository是一个相当重要的概念。聚合是战略与战术之间的交汇点。而管理聚合的正是Repository。 因为从战略层次,分而治之,我们会按领域、子域、界限上下文、聚合逐步划分降低系统复杂度;从战术层次,我们会从实体、值对象、聚合逐步归并,汇合。 也因此有人解析DDD关键就是两个字:分与合,分是手段,合是目的。 之前写的《DDD之Repository》[1],大致介绍了Repository作用。
先前已经对异常如何设计,如何实践异常都写了几篇阐述了。再一次从Clean Code角度来谈谈异常的使用。
并发问题的源头 并发?为啥需要并发呢?自然是为了性能,增强算力以及协调能力 在现今计算机器体系中,涉及性能的主要有CPU、内存、IO三方面,而这三者的速度也是天壤之别,形象之讲,CPU天上一天,内存是地上一年,IO则要地上十年
最近收到这样的问题: 领域服务做业务逻辑校验时应该返回错误码还是抛出业务异常? 这其实不算是领域服务的问题,而是Java异常处理[1]问题。 之前总结过一次如何处理异常[2] 上面的文章基本上就解决异常相关问题了。 这儿再回顾总结一下:
之前学习了极客时间上的一个专栏《软件设计之美》,作者对软件设计、编程范式、设计原则与模式、设计方法进行了讲解,内容全面。 专栏里面的一些内容,也有些接触,但认知还不够深,比如面向对象。而且专栏把这些内容都串联起来,跟着专栏内容总结梳理一下。
CQRS全称Command Query Responsibility Segregation
在做测试的时候,通常会临时替身来协助我们完成测试。
迪米特法则 Law of Demeter LOD 最早出现于 1987年,由美国东北大学的伊恩·霍兰德(Ian Holland)提出。也叫做“最少知识原则”。 Each unit should have only limited knowledge about other units: only units “closely” related to the current unit. Or: Each unit should only talk to its friends; Don’t talk to strangers.
几乎在每个团队,都至少有一份代码规范,或者代码的check list。然也就仅仅是一份清单。 每次团队复盘时,都会有一条,我们要写好代码,然“好代码”是什么样子,什么标准,全取决于各人的水平。 每个程序员也都知道code review的重要性,然排期很紧张,难得做一次。宁可花时间追查问题,也不做防御性准备。
从代码中,可以明显看出这是一段处理登陆请求的方法。在大多数项目中,这种代码很常见。 它有什么坏味道呢? 分层穿透了,LoginRequest类本应该属于入口层,结果穿透到了service层。 细细追究,需要明确的问题: 1、LoginRequest到底属于哪一层,是resource层,还是service层? 2、没有达到DDD防腐层的意义,resource是隔离外部与核心业务的,但却变成了透传。
使用缓存来加速应用程序的访问速度,是几乎所有高性能系统都会采用的方法。 但缓存真的那么好吗?架构师在构建高性能系统时,是不是必须增加缓存组件?缓存是不是多多益善? 《一代宗师》里本山大叔说过这样的一段话: “一门里,有人当面子,就得有人当里子。面子不能沾一点儿灰尘。流了血,里子得收着,收不住,漏到了面子上,就是毁派灭门的大事。”
微服务架构已经很流行了,并且有大量文章描述相对单体架构,微服务架构带来的众多优点。 怎么从单体架构更优雅地转化为微服务架构呢? 有一种被实践证明有效的方法论:The Twelve-Factor App[1]
这些年中台、微服务都是技术浪潮中的弄潮儿。两者的命运似乎是所有技术新词的缩影:先谈,再建,后拆,最后平静。 如中台,开始时聊什么都得带上中台,战略层喜欢谈,执行层也喜欢谈,再后面跟随一线大厂纷纷搭建自己的中台,然后就是反思,拆除中台,最后平静看待中台。 中台可以说已经经历完整的生命周期,而微服务周期也差不多,但对于“拆掉”,两者的声势与目标却不太相同。
之前总结了一篇文章《单服务器知识》[1],主要整理两方面的: 一是socket以及IO常识 二是单机高性能模式 你会一般不会出现socket连接IO相关知识结合,所以在学习IO的时候,总会有很多的背景知识,出现现在会很吃力,或者说不知道就在里面。 这是为什么呢?
不管在做系统分析,还是系统设计时,我们大概率都会提到领域模型这个词,奇妙的是虽然大家都在谈论领域模型,但每个人心中都有一份对领域模型的认知。 套用DDD,我们需要统一语言,首先需要对“领域模型”有一个统一认知。达成共识。 你可以暂时挂起大脑进程,想想:“领域模型是什么?怎么描述?” 世事万物都在变化中发展,就如同“手机”,十年前和现在,人们对它的认知也是不一样的。所以我们一起回顾一下最原始的“领域模型”是什么,你是否记起大明湖畔的领域模型。 “领域模型”最早流行于OOA中,简单回顾一下OOA/D
最近又看了几本关于架构的书籍,不禁回到原点:架构是什么?架构师职责是什么?架构 在《架构与架构师2》[1]中引用了1995年David Garlan和Dewayne Perry给出的定义: 系统的组件结构,组件的相互关系,以及管控组件设计和长期演进的原则和指导方针 十几年前,软件架构师只处理架构中的纯技术问题,像上面定义中的组件,可能是类,是包。而现在架构师承担着大量、宽泛的责任,并且范围还在不断扩大。尤其云时代,IT基础设施包括网络、数据中心、计算基础设施、存储,以及其他子系统都得考虑 贴一张思维导图来说明软件架构涵盖的范围
Eric在DDD第一章节就介绍了模型,可见模型的作用不言而喻,说DDD是一种模型驱动设计方法,绝对没有问题 那是不是我们在拿到业务需求时,就急呼呼的跟业务方来一起构造模型呢?毕竟模型是万事之首嘛 在《DDD开篇》[1]提过DDD是一种基于面向对象的设计方法,我们既然已经有了面向对象,而且OOAD也很强大,为什么还需要DDD呢? 要想弄清楚这两个问题,首先我们需要拿个示例来仔细比对一下
最近学到一个词“耦合创伤应激障碍”,讲的是程序员对耦合条件反射式恐惧,对于这个新词,我再重新理解一篇 对于一名程序员,从入行开始,就听到前辈们对“高内聚低耦合”的谆谆教诲,所以对于低耦合的意识深入骨髓。知行合一,看看是怎么践行的,打开任何一个项目工程,可以看到,每一个service都有一个interface和impl,代码看起来整整齐齐,所有变化点都考虑到了,但其实没有降低问题复杂度,只是自己看着舒服
资本家主要目标是赚钱、赚很多很多的钱;他们给提出的要求是降本增效 那么作为架构师,目标是什么呢? 在《整洁架构》书中作者写到架构的主要目的是支持系统的生命周期。良好的架构使系统易于理解,易于开发,易于维护和易于部署。 最终目标是最小化系统的寿命成本并最大化程序员的生产力
在之前《应对变化》[1]中提到模块之间合的策略:缩小依赖范围,API是两个模块间唯一的联结点
之前对SOLID做了一个总结 《SOLID》总结[1] 这些原则是前辈们经过无数实践提炼出来的,百炼成刚,那是不是成了放之四海皆准的道理呢?某种程度上讲,还真就是准的,常被人耳提面命写的代码要遵守这些原则,想想code review时,是不是代码常常对比这些原则,被人指出没有遵循哪个原则 总结篇中画了这幅图,SOLID也的确是我们达到高内聚低耦合很重要的手段
之前已经把SOLID的每人原则都阐述过一遍,此篇主要是从全局角度复述一下SOLID,对于细节概念再做少许补充 SOLID原则的历史已经很悠久,早在20世纪80年代末期,都已经开始逐渐成型了 通常来讲,想构建一个好的软件系统,应该从写整洁的代码开始做起。毕竟如果建筑的砖头质量不佳,那么架构所能起到的作用也会很有限。反之亦然,如果建筑的架构设计不佳,那么其所用砖头质量再好也没用
最近看到篇好文章《IO多路复用》,记得早期学习时,也去探索过select、poll、epoll的区别,但后来也是没有及时记录总结,也忘记了,学习似乎就是在记忆与忘记中徘徊,最后在心中留下的火种,是熄灭还是燎原就看记忆与忘记间的博弈 socket与io一对兄弟,有socket地方必然有io,io数据也大多来源于socket,回顾这两方面的知识点,大致梳理一下
同步异步I/O,阻塞非阻塞I/O是程序员老生常谈的话题了,也是自己一直以来懵懵懂懂的一个话题。比如:何为同步异步?何为阻塞与非阻塞?二者的区别在哪里?阻塞在何处?为什么会有多种IO模型,分别用来解决问题?常用的框架采用的是何种I/O模型?各种IO模型的优劣势在哪里,适用于何种应用场景? 简而言之,对于I/O的认知,不能仅仅停留在字面上认识,了解内部玄机,才能深刻理解I/O,才能看清I/O相关问题的本质。
为了讲多路复用,当然还是要跟风,采用鞭尸的思路,先讲讲传统的网络 IO 的弊端,用拉踩的方式捧起多路复用 IO 的优势。 为了方便理解,以下所有代码都是伪代码,知道其表达的意思即可。
之前的DDD文章中也指出过,现在从理论角度对于repository是错误,但一直没有摸索出最佳实践,都是当DAO使用,区别在于repository是领域层,也没有深入思考过 最近再次温习《DDD第二弹》时,看到了这个评论
对于Java理论在《Java异常处理》[1]中已经阐述了,看看理论如何指导落地 现流行的文章SpringBoot如何优雅处理异常,落地的确方便,使用AOP统一处理异常,但只是处理了api层次的异常
Java异常,本身知识体系很简单,但要设计好异常,却不是易事 Java异常如何使用,尤其checked exception,好些语言(c#,python)都没有此类型异常,只有unchecked exception;对于java为什么有checked exception,是不是设计过渡,在java初期被讨论了很多回,以及如何使用异常也被讨论了很多次,最近我在落地DDD时,又思考到此问题,不得不再翻回这个老问题,翻阅《Effective java》、《J2EE设计开发编程指南》这些经典
最近闲了,看了几次李运华关于架构的视频,不禁再次反问架构是什么?架构师的职责是什么? 对于这两个问题,之前也总结过一篇《架构和架构师》[1],再结合他的专栏文章和视频,补充一下
也不知code review是从哪年开始流行的,我的职场经历从刚开始完全没有到1对1,再到团队式review
近两年设计了几个系统,不管是直接使用传统设计ER图,还是使用4C建模,但在做架构评审时,ER却都是重中之重,让人不得不深思,编程思想经过了一代代发展,为什么还在围绕ER,在远古时代,没有OO,没有DDD,但为什么延续至今的伟大软件也比比皆是 带着这个问题,需要回头看看,结构化编程为什么不行?面向对象因何而起,到底解决了什么问题? 《架构整洁之道》也特别介绍了面向对象编程,面向对象究竟是什么,大多从三大特性:封装、继承、抽象说起,但其实这三种特性并不是面向对象语言特有
之前整理过《DDD分层》[1] 以及《分层架构》[2] 最近看网友讨论,整理一些有亮点的地方 现在分层架构+整洁架构似乎是个万金油组合了 之前DDD的标准分层结构:
阿里殷浩大牛写了DDD系统文章,现在已经更新到每四篇,有很多异于常规的地方,收获良多,总结一下
DDD开篇总结》[1]的前三篇已经阐述了几个内容 1.DDD是什么2.复杂系统的特征3.DDD如何应对复杂系统4.模型概念5.软件开发流程 但一般DDD资料中都会分为两部分讲述:战略和战术,所以按这两种分类,重新归纳整合一下
之前写了两篇《DDD开篇》[1]与《DDD应对复杂》[2],是时候总结一下了 对于DDD的启蒙,不管是国内还是国外思维逻辑都是一样的。或者说如果你想写本关于DDD的书,大纲似乎是一样的 首先DDD是什么?给出定义,定义有些抽象,难以一次性接受,那就通过以往问题引出DDD,这时模型、复杂度、开发流程都是自然附带出的概念,再后面就是DDD的知识结构是什么,最后就是讲解一个实例,也有些会把实例穿插到各个篇章中
复杂 Eric Evans所著副标题--Tackling Complexity in the Heart of Software,对于简单系统其实没有必要使用DDD,只有在复杂系统中,才能体现DDD的价值 那么何为“复杂”,或者说为什么软件是复杂的呢?
从知道DDD到现在已经很多年了,看了不少理论知识,在项目中也使用了DDD,碰到些问题,也有些思考,整理一下,上升一下,形成一种适合自身的方法论 在回顾过程中,首先追根溯源,什么是DDD?为什么要使用DDD?如何给别人阐述这些最基本的概念与理念,真是个难题
最近一季度KPI中,增加了一项单元测试覆盖率 在之前工作经历中,也有过类似情况,老板开始关注单元测试情况了,就会加上覆盖率这个绩效指标,不管以前如何应对,还是再次关注了一些对于测试的文章,TDD虽然没有大流行,但这个概念还是常被人提起
最近在团队中引入checkstyle[1] ,自动执行规范检查,加入到ci步骤里面,让流程工具化,工具自动化,摆脱人工检查,在团队开发中硬性统一,更便于协作顺畅 checkstyle里面有个规范:所有local variable必须修饰为final 这是为什么呢?
为什么分层 引用《领域驱动设计模式、原理与实践》 为了避免将代码库变成大泥球(BBoM)并因此减弱领域模型的完整性且最终减弱可用性,系统架构要支持技术复杂性与领域复杂性的分离。引起技术实现发生变化的原因与引起领域逻辑发生变化的原因显然不同,这就导致基础设施和领域逻辑问题会以不同速率发生变化 每一层都有各自的职责,显然这也是符合SRP的
早时总结过《ThreadLocal解析》、《FastThreadLocal解析》 最近看一些资料的时候,又重重发现了这类,不希望再温下,许多知识点,之前已经总结了,这篇文章主要有两个问题: 1、弱引用的意义 2、如何防键冲突
可知上一篇【死锁分析】,又重新表达了一些图片,图画更了
最近新项目上线,在压测和发布生产都出现了好几种死锁情况,分析一二
《DDD之形》把当前一些流行的架构给通览了一篇,那是不是万事大吉,随便挑一个形态实践就行呢? 正常情况对于有追求的程序员来讲,肯定不行,有两个原因 一因为完美,人人都是想要完美,每个架构实践都不是完美的,尤其离开业务场景去探讨架构,会使架构没法落地;因此你小抄的时候会变形,想把原先至少不太好的地方改得相对好些,但这样可能造成四不像
从年初就开始温习SOLID原则,原则看似很简单,有些其实就是一句话,但对照这些原则去观看自己的过往代码,还是很多违背这些原则的,诚然,没有完美的实践,但需要保持在走向完美的路上 当然,如果你说天天在CRUD,从没有用到过这些原则,这就是另一个话题了 最近就写了一段很臭的代码,反省一下
接口隔离原则,ISP,Interface Segregation Principle 用于处理胖接口(fat interface)所带来的问题。如果类的接口定义暴露了过多的行为,则说明这个类的接口定义内聚程度不够好
DDD现在已然变成哲学,正因为是哲学,所以法无定法,到底怎么具体怎么实施,各显神通,心法固然重要,但心法有几人能真正领悟,一说就懂,一问就不会,一讨论就吵架;所以还是从外形看看,收集一些实践后的形态,由表入里,以形学形,慢慢品 看下面两个分层,左边是Vaughn Vernon 在《实现领域驱动设计》一书中给出了改良版的分层架构,他将基础设施层奇怪地放在了整个架构的最上面;右边就是DDD最标准的分层形态
最近连续做了两个新项目,借着新项目的机会,重新审视一下之前一些实践方法,进而寻求一下背后的理论支撑 新项目开始,首先一个就是会新建一个project,那么这个project怎么分层,怎么创建module,怎么分包呢?
究竟什么才是“软件架构”?架构师的工作内容究竟是什么? 架构 “架构”这个词给人的直观感受就充满了权力与神秘感,因此谈论架构总让人有一种正在进行责任重大的决策或者深度技术分析的感觉。毕竟,进阶到软件架构这一层次是我们走技术路线的人的终极目标
里氏代换原则 LSP,Liskov Substitution Principle 子类型必须能够替换掉它们的基类型 若对每个类型S的对象O1,都存在一个类型T的对象O2,使得在所有针对T编写的程序P中,用O1替换O2后,程序P行为功能不变,则S是T的子类型 LSP是继承关系设计基本原则,也是使OCP成为可能的主要原则之一。正是子类型的可替换性才使得使用基类类型的模块在无需修改的情况下就可以扩展,对于LSP的违反常常会导致以明显违反OCP的方式使用运行时类型辨别(RTTI),这种方式常常是使用一个显式的if语句或才if/else链去确定一个对象的类型