尽管这可以让开发人员觉得理解和开始工作变得简单了许多,是一个很好的起点,但是使用CRUD作为API的起点,我有一个很大的疑问。就是CRUD中的U是我最不喜欢的。...当然,并不是说你必须使用DDD来设计你的REST,但是,由于REST资源可以很好地映射到DDD实体,因此我发现设计REST API特别适合使用DDD。 那么这是什么意思?...对于银行API,明显的领域对象(或DDD术语中的实体)是一个帐户,它为银行帐户建模。我们不应该按照帐户的CRUD模型来定义在银行账户上执行的具体业务操作。以下是一个写操作系列很好的开始: 1....以这种方式定义你的API需要更多的前瞻性思考,要比简单的CRUD 生成器需要花费更多的思考,但我认为这是值得的也是必须的。...因此不应该按照CRUD模型来构建你的serviceAPI(REST 或其他),而应该是使用DDD,DDD可以根据领域对象和可对其执行的业务操作来定义API。
来自亚马逊的高级工程师 James Hood 以简单明了的例子说明了为什么要用 DDD 替代 CRUD 来设计 REST API。...虽然这给开发者带来了便利,但我觉得这样是有问题的。我不喜欢 CRUD 这样的说法,尤其不喜欢当中的 U。...问题:CRUD 中的 U 一般的更新操作允许客户端更新资源的任何一个字段,并使用新版本覆盖已有的版本。但如果你允许客户端这么做,那么你的服务 API 就失去了应有的价值。...解决方法:DDD 那么该如何解决这个问题,有其他更好的方案吗?我个人更喜欢基于领域驱动设计(DDD)来设计 API。DDD 的基本思想是说,软件的建模应该发生在真实世界的问题得到解决之后。...对于银行的 API 来说,账户就是一个领域对象(DDD 里的实体)。这次我们不再使用 CRUD 来为账户建模,而是为账户定义一组业务操作。以下是一系列写入操作: 开户(Open)——新开一个账户。
从前缀来看,根据DDD的经典分层架构,它们又隶属于不同的层,应用服务属于应用层,领域服务属于领域层。 ?...应用服务 应用服务是用来表达用例和用户故事(User Story)的主要手段。 应用层通过应用服务接口来暴露系统的全部功能。...在应用服务的实现中,它负责编排和转发,它将要实现的功能委托给一个或多个领域对象来实现,它本身只负责处理业务用例的执行顺序以及结果的拼装。通过这样一种方式,它隐藏了领域层的复杂性及其内部实现机制。...5.总结 当应用服务中的逻辑趋于复杂时,我们就要小心领域逻辑泄露到应用服务中去。而在使用领域服务时,我们又要避免过度使用,因为会导致贫血领域模型。...应用服务不处理业务逻辑,领域服务处理业务逻辑。 参考资料 DDD与分层架构--秋水逍遥
展现数据非常有用,但是当我们考虑到DDD的目标时,客户方的限界上下文是不会原封不动地消费这些JSON数据的。...其中,虚线表示的是依赖注入原则(4),而实线则表示操作分发。比如,基础设施实现了用户界面、应用服务和领域模型中的抽象接口,同时它还将操作分发给应用服务、领域模型和数据存储。...应用服务通过资源库(12)读取所需的聚合实例,然后使用一个DTO组装器(DTOAssemble)[Fowler, P of EAA]将需要显示的属性值映射到DTO中。...应用服务(请参考“应用服务”一节)通过资源库获取到所需聚合实例,然后创建DPO实例,该DPO持有对所有聚合实例的引用。之后,展现组件通过DPO获得聚合实例的引用,再从聚合中访问需要显示的属性。...在使用Spring时,该端口类可以被注入到应用服务中。此时,provisionTenant()方法唯一需要知道的便是调用write()方法把从领域服务中获取到的Tenant实例写到端口中。
在领域建模的过程中,建立领域对象间的“关联(Association)”也是非常重要的。《DDD》第5.1节对此进行了专门的讨论。不过与实体不同,艾老师并没有把关联当做一种正式的“模式”。...这强调了,只有充分了解事物之间的联系,才能充分认识事物。 DDD中,领域(事物)的概念以实体、值对象、聚合、模块等方式表达出来。...真想做到模型的演进,不仅需要上述《DDD》中的建模技能,还要扎实地掌握重构、TDD(或者至少是自动化测试)和持续集成,我将之称为敏捷工程实践的“老三样”。...联系到模型的演进,我们从《DDD》中的相关例子看到,随着对领域知识理解的深入,模型的重构往往不是多了几个实体、少了几个关联,而是多出了若干抽象层次,甚至将模型的核心部分打碎重组。...其实《DDD》和《演进式架构》是两本书。两者的侧重点不同,一本侧重领域建模,一本侧重系统架构演进。不过在实践中我们常常将两者结合起来运用。下面聊两句演进式架构的原理,这超出了《DDD》原书的范围。
对领域这个词的理解就是 DDD 入门的第一个难关。我们有时会被客户问到,领域到底是什么?首先要清晰地知道领域是什么,才能划分核心域、支撑域和通用域。换句话说,构成领域的要素是什么呢?...DDD 软件建模就是业务问题和解决方案之间的桥梁。领域是问题,设计出来的模型是解的一部分。因此,问题和解形如 x 和 f(x) 的关系,f = 软件建模过程。...聚合被赋予了两个责任: 负责业务的一致性。 负责数据的整体存储。 而其持久化是一个老大难问题。 关于业务的一致性,Eric DDD 给我们描述了一种理想情景。...充血模型已经是很多 DDD 实践者的潜在认知,简单来说就是把业务行为放到模型中。 这种做法看似满足了面向对象的实践,但是在实际工作中,它并不方便,甚至有些别扭。...在培训中,有学员找我们说,学了 DDD 之后不会写代码了,甚至忘记之前的代码该如何编写。 极端一点的例子,还会有人在聚合根中调用仓储来实现聚合的存储。
1 没有DDD时的问题解决 这些项目导致与产品部门来回讨论,以真正理解所需的行为并了解可能的边界情况,结果是无效的会议和浪费时间。 这正是DDD进入软件世界要解决的问题。...DDD 是一套用于有效处理问题并高效地通过业务软件解决问题的技术。 在这篇文章中,我不会向你解释什么是DDD,因为我假设如果你正在阅读这篇文章,那么你已经有了一些背景知识。...有了DDD,最初描述的场景看起来完全不同。DDD的目标是让所有领域专家使用相同语言(统一语言,Ubiquitous Language)并共享对问题的相同理解。...此外,象形语言是基于范围的,也就是说,它取决于绘制图表时使用的范围。开始绘制图表时需要考虑三种范围: 颗粒度——用来表示图表中的故事的细节级别。...显然,我们并没有深入到太多细节,而且这是使用的纯粹范围。 一旦我们绘制了这个图表,就该开始识别界限上下文了。在这个例子中,我们可以将其分为两个BC:“风险评估”和“销售”。
领域服务可能是最容易被误解的 DDD 模式,各种 Web 框架都对此感到困惑。在许多框架中,服务承担着多种角色。...然而,在使用 Go 时,通常对整个应用程序使用域服务的单个实例。因此,当多个客户端访问内存中的相同值时,必须考虑后果。...4.1 应用服务 type AccountSessionService struct { accountService AccountService } func (s *AccountSessionService...= nil { return nil, err } return account, nil } 在许多情况下,我使用应用服务作为域服务的包装结构。...在此示例中,AccountSessionService用作应用服务,包含域层的功能AccountService。它的职责是从会话存储中检索值,然后利用它来Account从底层服务中检索详细信息。
这篇文章主要介绍下,如何通过webpy的db模块完成crud操作。一开始觉得webpy的db模块写的太绕了,现在仔细看了源代码之后,发现确实封装的过于多了点,把一个sql语句各种拆。...相对于简单的sqlhelper来说——比如tornadb,这个东西复杂了点,对于ORM来说,这东西有简单了点。...不过想起最早时我在写vb或者.net的时候自己写sqlhelper也有过此类的想法,把sql语句的各个部分都给封装起来。...关于某个工具或者类的解释,通过代码能表达得更加直观: #coding:utf-8importwebdb=web.database(dbn='sqlite',db="todos.db")classTodos...kwargs)@staticmethoddefdelete(id):db.delete('todos',where="id=$id",vars=locals()) 这其实是对todos进行服务器端扩展的一部分代码
大家好,又见面了,我是你们的朋友全栈君。 一、背景 在之前的文章中已经介绍了DDD相关的概念模式,DDD相关的业务技术架构,但是我们还没有找到一个核心的抓手去实践DDD。...DDD的一个核心本质就是对业务建模,或者领域建模。说的很简单,但是做好确实很难,一个需求过来意淫几个实体对象就差不多解决了。深入看,全局看只在脑海中进行的建模实际上并不一定正确和稳定。...说明:在建模中对上述颜色表示的内容进行解释,用于分类或者描述建模过程中产生的数据,事件,或者活动。...注:这里的时标对象就是业务发生时刻。聚集就是DDD中的聚合模式。...,如促销系统中抽象出促销产品,权限系统中抽象出授权) 找出领域模型中的聚合,以及每个聚合的聚合根 梳理聚合之间的关系 场景走查,检查领域模型如何满足用例需求 5.3 实战案例 商品发布场景建模过程:
--统计未进行逻辑删除的课程--> 206 207...--统计多个分类下的课程数目--> 213 214 SELECT...–给予课程Id查询课程所属的一二级部门部门–> 388 <select id="queryCourseAffiliation" resultType="com.qunar.qexam2
今天我们谈一谈如何使用DDD重构中台业务。 DDD有两把利器,那就是它的战略设计和战术设计方法。中台在企业架构上更多偏向业务模型,形成中台的过程实际上也是业务领域不断细分的过程。...这里我要提醒你一下:根据DDD首先要建立通用语言的原则,在将DDD的方法引入中台设计时,我们要先建立中台和DDD的通用语言。这里的子域与中台是一致的,那我们就可以将子域统一为中台。...当完成业务建模后,我们就可以采用DDD战术设计,设计出聚合、实体、领域事件、领域服务以及应用服务等领域对象,再利用分层架构模型完成微服务的设计。 以上就是DDD、中台和微服务在应用过程中的协作模式。...中台如何建模? 中台业务抽象的过程就是业务建模的过程,对应DDD的战略设计。系统抽象的过程就是微服务的建设过程,对应DDD的战术设计。下面我们就结合DDD领域建模的方法,讲一下中台业务建模的过程。...总结 今天我们主要讨论了传统企业中台建设的一些思路,梳理了DDD、中台和微服务的关系。DDD的战略设计可用于中台业务建模,战术设计可指导中台微服务设计。
DDD四层架构模式中,各层的对象我们需要借助assembler或converter来进行转换,但在实际项目中assembler和converter大家使用都很随意,很多项目中每一层都建了一个assembler...) 这里从英文意思上似乎找不到区别的方法,assembler 虽然有将指令转变为机器码的含义,但开发中实际也不是拿来转换成机器码,和 converter 一样是拿来做对象之间的转换。...实际开发中例如在电商场景下,一个订单聚合根对象可能需要由订单信息、用户信息、物流信息等多个部分组成,assembler 的任务就是将这些各个信息装配成一个完整的订单聚合根对象,使得这个新的对象在领域层,...还是比如在电商系统中,领域层有一个包含了详细用户信息(如姓名、年龄、性别、联系方式、收货地址等)的用户对象。...两种区分方法似乎都有其合理性,但是按语义区分的方式实际在开发中很难明确区别出来,也就很容易造成后续开发者不明其理随意使用。
了解了DDD的好处与基本的核心组件后,我们先不急着进入支持DDD思想的轻量级框架开发,也不急于直销系统需求分析和具体代码实现,我们还少一块, 那就是经典DDD的架构,只有了解了经典DDD的架构,你才能知道具体在哪层要实现哪些功能...在这里需要说明的是,我们的大健康行业直销系统有一定的业务复杂性,没有高并发、高性能的需求,所以无论是经销商上下文、产品上下文还是订单上下文的具体实现, 我们都将遵循经典DDD架构,而不是CRUD简单方式或...c.聚合根仓储实现:这个.net core项目严格来讲其实不属于基础结构层部分,只是由于习惯,把它放到基础结构层这个解决方案文件夹中。...c.定义该界限上下文聚合根的仓储接口,这个接口代表的是聚合根与持久化打交道的基础约束,具体实现还是在基础结构层的聚合根仓储中实现,这样就实现了解耦。...3.应用服务层:界限上下文的用例 a.某个上下文的应用服务层的某个用例,通过调用领域对象的领域逻辑,完成相关领域逻辑的实现。
在社区经过了几年的实践之后,已经有了文档和流程之后,接下来,就是工具化了:如何将 DDD 固化到软件设计与开发流程中?市场上已经有一系列的工具,诸如于大家经常吐槽的 COLA 做了类似的事情。...统一 DDD 的统一语言 尽管,我司(Thoughtworks)会在各类的 DDD 工作坊中强调,统一语言的重要性。...最后,我们还有考虑的问题是,如何对 DDD 中采用的模式部分进行抽象?诸如于 如何用代码化的方式,表示采用 Factory、Repository、Service、Event 等开发模式进行表示?...小结 我不并擅长建模,我一直觉得模型在重构的过程中,自然而然就会浮现出来。而除了重构的这种方式,还有一种额外的方式是借助 DSL(领域特定语言)进行抽象。...所以,我尝试以此作为一些出发点,借而来 Driven 中系统的模型。与得到一个有用的结果相比,在过程中对于 DDD 的抽象,构建 DDD 的 DDD 模型,显得更有意思。
ElasticSearch的简单的CRUD 2. 添加索引 3. 检索文档 4. 删除文档 5. 修改文档 5.1. 直接覆盖全部 5.2. 部分更新 6....参考文档 ElasticSearch的简单的CRUD 1、ElasticSearch使用的是RestFul风格的API 2、http://39.105.123.197:5601/ 添加索引 1、需要指定索引...,文档的类型,文档的Id 2、使用PUT风格的提交方式,如下: 1、`group`:索引名称 2、`employee`:文档的名字 3、`1`:对应的id PUT /group/employee/1..._source指定文档中的变量,这里的是将views加1 POST /megacorp/employee/2/_update { "script" : "ctx...._source.views+=1" } 4、更新可能不存在的值,如果这个值不存在,那么就添加进去,这个很像MongoDB中的检索,使用upsert完成,如下: POST /megacorp/employee
MyBatis的增删改查,特点是只要定义接口,不用实现方法,sql语句在xml中配置,非常方便 文件结构 ?...--配置mysql的环境--> 的位置--> 的问题--> --> /*配置插入操作后,获取插入数据的id
2.es会将老的document标记为deleted(逻辑删除),然后新增我们给定的一个document,当我们创建越来越多的document的时候,es会在适当的时机在后台自动删除(物理删除)标记为deleted...之后,我们可以从侧面证明,它不是立即物理删除的,因为它的一些版本号信息还是保留的。...phrase search:要求输入的搜索串,必须在指定的字段文本中,完全包含一模一样的,才可以算匹配成功,才能作为结果返回。...25 } } ], "minimum_should_match" : 1 } } } 多条件查询中的字段描述...总结 以上是对Elasticsearch的简单的增删改查做了一点点总结。简单的逻辑足够,但是有些需求需要比较复杂的查询,我们下次再学。
在前文《当我们谈论DDD时我们在谈论什么》中我们讨论了DDD的战略设计和战术设计。在本文中我们将继续探讨领域模型。...应用服务利用Repository获取需要修改的活动,再根据运营人员提供的参数修改活动,最后利用Repository保存活动对象。 用户参与活动。应用服务: 使用活动通用规则判断用户是否可以参加。...由于活动通用规则需要用到活动参与记录,因此应用服务会使用Repository获取活动参与记录; 如果可以参加,则执行活动的参与活动方法获得结果。...活动参与记录实际上是不可变的,可以将其设计为领域事件。 用户参与活动的用例里,逻辑复杂,有泄漏领域概念的嫌疑? 如果发现应用服务里逻辑变得复杂,可能意味着我们找到了一个隐藏的领域概念。...总结 很多项目虽然也使用了以领域模型为中心的架构,但是设计者仍然是数据模型/贫血领域模型的思考方式,把大量领域逻辑放置在了万能的Service中,让领域概念隐藏在了冗长的过程代码中,无法享受到DDD带来的收益
Mapper CRUD接口 一、CRUD接口 1.1 Insert 1.2 Delete 1.3 Update 1.4 Select 二、测试 2.1 pom.xml 2.2 Employee.java...接口 说明: 通用 CRUD 封装BaseMapper (opens new window)接口,为 Mybatis-Plus启动时自动解析实体表关系映射转换为 Mybatis 内部对象注入容器...TableName(value = "tbl_employee") public class Employee { /** * @TableId: * value:指定表中的主键列的列名...,只有非空的属性对应 //的字段才会出现到sql语句中 Integer result = employeeMapper.insert(employee);...System.out.println("result:"+result); //获取当前数据在数据库中的主键值 Integer key=employee.getId()
领取专属 10元无门槛券
手把手带您无忧上云