2017

请先阅读这2篇文章: 程序员你为什么这么累? 我的编码习惯 - 接口定义 第一篇文章中,我贴了2段代码,第一个是原生态的,第2段是我指定了接口定义规范,使用AOP技术之后最终交付的代码,从15行到一行,自己感受一下。今天来说说大家关注的AOP如何实现。 先说说Controller规范,主要的内容是就是接口定义里面的内容,你只要遵循里面的规范,controller就问题不大,除了这些,还有另外的几点: 所有函数返回统一的ResultBean/PageResultBean格式 原因见我的接口定义这个贴。没有统一格式,AOP无法玩。 ResultBean/PageResultBean是controller专用的,不允许往后传! Controller做参数格式的转换,不允许把json,map这类对象传到services去,也不允许services返回json、map。 一般情...

导读: 程序员你为什么这么累? 我的编码习惯 - 接口定义 我的编码习惯 - Controller规范 我的编码习惯 - 日志建议 我的编码习惯 - 异常处理 我的编码习惯 - 参数校验和国际化规范 我的编码习惯 - 工具类规范 我的编码习惯 - 函数编写建议 我的编码习惯 - 配置规范 工作中,少不了要定义各种接口,系统集成要定义接口,前后台掉调用也要定义接口。接口定义一定程度上能反应程序员的编程功底。列举一下工作中我发现大家容易出现的问题: 1. 返回格式不统一 同一个接口,有时候返回数组,有时候返回单个;成功的时候返回对象,失败的时候返回错误信息字符串。工作中有个系统集成就是这样定义的接口,真是辣眼睛。这个对应代码上,返回的类型是map,json,object,都是不应该的。实际工作中,我们会定义一个统一的格式,就是ResultBean,分页的有另外一个PageResult...

大家一提到程序员,首先想到的是以下标签:苦逼,加班,熬夜通宵。但是,但凡工作了的同学都知道,其实大部分程序员做的事情都很简单,代码CRUD可以说毫无技术含量,就算什么不懂依葫芦画瓢很多功能也能勉强做出来,做个多线程并发就算高科技了,程序员这行的门槛其实还是比较低的。(这里说的是大部分,有些牛逼的,写算法、jvm等的请自动跳过) 是不是觉得很矛盾,一方面工作不复杂,一方面却累成狗。有没有想过问题出在哪里?有没有想过时间都花在哪里呢? 对于我个人来说,编码还是一个相对轻松的活(我是负责公司it系统的,没有太多技术含量,数据量大,但并发量不大)。从工作到现在,我加班编码的时间还是比较少的,我到现在为止每天还会编码,很少因为编码工作加班。 大家写的东西都是一些crud的业务逻辑代码,为什么大家这么累,加班加点天天都是奋斗者?我从自己带的项目中观察中发现,大部分人的大部分时间都是在 定位问题 ...

DDD社区官网上一篇关于聚合设计的几个原则的简单讨论:文章地址:http://dddcommunity.org/library/vernon_2011/,该地址中包含了一篇关于介绍如何有效的设计聚合的一些原则,共3个pdf文件。该文章中指出了以下几个聚合设计的原则: 聚合是用来封装真正的不变性,而不是简单的将对象组合在一起; 聚合应尽量设计的小; 聚合之间的关联通过ID,而不是对象引用; 聚合内强一致性,聚合之间最终一致性; 上面这几条原则,作者通过一个例子来逐步阐述。下面我按照我的理解对每个原则做一个简单的描述。 聚合是用来封装真正的不变性,而不是简单的将对象组合在一起这个原则,就是强调聚合的真正用途除了封装我们本身所关心的信息外,最主要的目的是为了封装业务规则,保证数据的一致性。在我看来,这一点是设计聚合时最重要和最需要考虑的点;当我们在设计聚合时,要多想想当前聚合封装了哪些...

领域驱动设计之领域模型2004年Eric Evans 发表Domain-Driven Design –Tackling Complexity in the Heart of Software (领域驱动设计),简称Evans DDD。领域驱动设计分为两个阶段: 以一种领域专家、设计人员、开发人员都能理解的通用语言作为相互交流的工具,在交流的过程中发现领域概念,然后将这些概念设计成一个领域模型;由领域模型驱动软件设计,用代码来实现该领域模型; 由此可见,领域驱动设计的核心是建立正确的领域模型。 为什么建立一个领域模型是重要的领域驱动设计告诉我们,在通过软件实现一个业务系统时,建立一个领域模型是非常重要和必要的,因为领域模型具有以下特点: 领域模型是对具有某个边界的领域的一个抽象,反映了领域内用户业务需求的本质;领域模型是有边界的,只反应了我们在领域内所关注的部分; 领域模型只反映业务...

消息场景:用户 A 发送一个消息给用户 B,用户 B 回复一个消息给用户 A。。。 现有设计:消息设计为实体并为聚合根,发件人、收件人设计为值对象。 三个问题: 实体最重要的特性是什么? Message 实体是怎么得来的? 发件人、收件人为什么不是实体? 1. 实体最重要的特性是什么?《领域驱动设计》5.2 实体: 摘录一段:许多对象不是由它们的属性来定义,而是通过一系列的连续性(continuity)和标识(identity)来从根本上定义的。 归纳: 标识(identity) 连续性(continuity) 标识在实体中的另一种体现就是唯一和不可变,其概念在很多资料中有说明,这也是实体最重要的特性。 我有一个双胞胎哥哥,我们俩出生的时候,长得一模一样,以至于我们的爸妈都分不清,不得已他们在我们脖子上系个项链来标记:谁是老大?谁是老二?其实这个“标记”就可以看作是实体的...

做一枚全栈工程师 如果一个全栈工程师能够根据原型实现一个完整的MVP(minimum viable product,至少可行的产品),我们通常会认为他十八般武艺样样精通,而且有足够的理由来证明这一点。为了给全栈工程师一个最新鲜的定义,我们首先来关注一下全栈工程师以前是搞什么的。 以前的全栈工程师很久以前,大约在 2000 年(在互联网的次元里,17年可以说是一个非常长的时间了),一个全栈工程师必须掌握下面的本领: 用 Adobe 公司的 Photoshop 或者 Fireworks 工具设计出一个网页 将设计稿变成 HTML, CSS 还有热点图(额,还记得那些吗?) 写一些基本的 PHP 4.0 脚本(非面向对象的 PHP 即将成为历史)来处理服务端逻辑 保存所有的动态数据到 MySQL 中,也可能会做一些小优化 用 FTP 上传所有代码、数据库什么的到一台服务器,然后...

HelloPWS(Pivotal Web Service),由 Pivotal 公司提供的 ,可以运行Java, Grails, Play, Spring, Node.js, Ruby on Rails, Sinatra or Go 等Web应用的服务。本文将介绍一个 Hello World 级别的 Spring Boot 应用发布到 PWS 的过程。 武器 CentOS 7.3 OpenJDK 1.8.0_141 Maven 3.0.5 准备战斗1、在 https://run.pivotal.io/ 注册一个账号,完成手机绑定。 2、在 Github 上克隆一个 Spring Boot 的 hello world 的项目。 git clone https://github.com/spring-guides/gs-spring-boot.git 好戏开场1、安装 cf CLI ...

通过之前几篇Spring Cloud中几个核心组件的介绍,我们已经可以构建一个简略的(不够完善)微服务架构了。比如下图所示: 我们使用Spring Cloud Netflix中的Eureka实现了服务注册中心以及服务注册与发现;而服务间通过Ribbon或Feign实现服务的消费以及均衡负载;通过Spring Cloud Config实现了应用多环境的外部化配置以及版本管理。为了使得服务集群更为健壮,使用Hystrix的融断机制来避免在微服务架构中个别服务出现异常时引起的故障蔓延。 在该架构中,我们的服务集群包含:内部服务Service A和Service B,他们都会注册与订阅服务至Eureka Server,而Open Service是一个对外的服务,通过均衡负载公开至服务调用方。本文我们把焦点聚集在对外服务这块,这样的实现是否合理,或者是否有更好的实现方式呢? 先来说说这样架构...

REST围绕着资源这个概念而构建的,然后用URI来表示。然后一个HTTP动词和资源URI组合起来对指定资源进行HTTP调用来执行操作。大多数REST框架提供了指定资源名称的生成器,框架围绕着它来生成脚手架。不幸的是,许多这些生成器使用CRUD模型(Create,Read, Update, Delete)作为默认的起始点。资源被定义为一系列的属性,使用类似JSON Schema或某个具体语言的数据对象来定义,然后生成方法存根,然后来创建,读取,更新和删除该资源。 尽管这可以让开发人员觉得理解和开始工作变得简单了许多,是一个很好的起点,但是使用CRUD作为API的起点,我有一个很大的疑问。就是CRUD中的U是我最不喜欢的。让我们来谈谈U.通用更新方法允许客户端更新资源的任何字段,然后使用新版本覆盖现有版本。但是,如果允许客户端执行这样的操作,您的服务API在其使用的任何底层数据存储之上,...

简介该项目主要利用Spring Boot的自动化配置特性来实现快速的将swagger2引入spring boot应用来生成API文档,简化原生使用swagger2的整合代码。 GitHub:https://github.com/dyc87112/spring-boot-starter-swagger 码云:http://git.oschina.net/didispace/spring-boot-starter-swagger 博客:http://blog.didispace.com 小工具一枚,欢迎使用和Star支持,如使用过程中碰到问题,可以提出Issue,我会尽力完善该Starter 版本基础 Spring Boot:1.5.x Swagger:2.7.x 如何使用在该项目的帮助下,我们的Spring Boot可以轻松的引入swagger2,主需要做下面两个步骤: 在po...

我以前写过一篇关于领域事件的文章——实现领域事件,随着在项目中深入的使用DDD架构,我对领域事件有了新的认识。尤其是采用领域事件来解耦代码这种方式对项目的发展具有深远的影响。 我在实现领域事件中主要谈到了如何在技术层面去实现发布事件与订阅事件,比较了几种不同的方式以及它们背后的原理。但随着我在自己负责的项目中严格地实施DDD架构时,我发现如何去发布订阅领域事件的意义远没有决定去做这件事情本身重要。换句话说,与其纠结与是使用基于Spring的事件架构还是Guava提供的EventBus,是使用同步发布还是异步发布,还不如想想去做这件事情对你的项目会产生怎样的影响。 为什么要使用事件?我认为这是所有人应该考虑的首要问题。对我来说,使用事件的意义有两个方面,一是在于流程上的解耦,二是在于代码层面的解耦。在代码层面的解耦是显而易见的,我就不再赘述了。那么流程上的解耦是什么意思了?我们先看一下...

当你的系统或者业务变得日益复杂时,DDD的模式是一种非常值得尝试的架构模式。DDD让你更加关注于你的业务领域,思考你的业务模型,帮组你理清繁杂的业务关系。我推荐所有还没有了解过或者接触过DDD的后端工程师都去学习一下该架构模式。本文主要关注DDD中的领域事件,以及一种可能的实践方式。 我们知道领域模型的变化会产生领域事件。例如,用户在完成注册后,系统会发出一封带有确认信息的邮件到用户的邮箱;用户关注的好友发送动态后他会收到相应的通知等等。在业务比较简单或者不用考虑性能的情况下,我们可以直接把对领域事件的处理嵌入到领域服务中。考虑这样一个场景:用户回复了某条评论,那么被回复的那个用户(也就是那条评论的所有者)需要收到一个PUSH消息。这个场景比较简单,我们可能直接写出类似下面的代码: void reply(long fromUserId,long toUserId,String ...

相信有很多童鞋跟我一样,热衷于用Markdown来编写文章。由于其简单的语法和清晰的渲染效果,受到广大码农朋友们的推崇。但是,当我们想维护起自己的公众号时,公众号编辑器往往让我们费劲了脑汁。本人尝试了各种工具,比如:秀米一些在线提供多种不同样式的编辑器。虽然这些编辑器都能够完成编辑任务,但是效果并不理想。与我们所追求的简洁、清晰风格总是格格不入,尤其是对于代码的展示非常的不友好。所以,这里给大家推荐一个本站的在线工具,可以帮助大家快速地把Markdown文章转换成微信公众号支持的漂亮格式。 首先奉上本文即将介绍的工具地址:http://blog.didispace.com/tools/online-markdown/ 最新版本:http://md.openwrite.cn/ 全新的用户体验,已远优于下面的介绍,建议直接进入体验! 使用方法该工具的使用非常非常简单,点击http:/...

关于领域驱动设计这篇文章参考了Eric Evans《领域驱动设计》一书以及Jimmy Nilsson《以C# .NET为例运用领域驱动设计和模式》,二者详细描述了领域驱动设计的核心概念、技术和模式。在某些情况下,直接使用这些书的措辞是有意义的,并且我认为Eric Evans和Jimmy Nilsson也允许我们这么做。 尽管将方法本身呈现出来是很有用的,但是仅仅对方法进行描述,DDD的许多微妙之处就会消失。这些方法应该是你的工具,而不是你束缚你的规则。它们是为设计而生的语言,在团队内沟通创意和模型十分有益。更为重要的是,记住实践DDD的目的是为了做出更加务实的决定。不要试图将一个方法强加于一个模型。另外,如果你“打破”了一个方法,确保你已经理解了这么做的理由,并将其与其他人沟通。 通常认为,DDD在面向对象范式下表现良好,但远不止这些。DDD解决了如何去理解问题空间这一挑战,甚至是更...