《Akka应用模式:分布式应用程序设计实践指南》读书笔记3

分布式领域驱动设计

  DDD领域驱动设计,应该就是一种系统设计的方法论,可以知道人们设计软件。其实老外就喜欢总结一些方法论用于指导实践,这一点还是很重要的。

DDD概述

  DDD是一套关于软件架构的指导原则。最重要的概念就是域模型。“域”是构成尝试建模的业务或领域的一组要求、约束和概念。我们可以理解成一个设计良好的OOP中的一个类,但在DDD中域更加注重描述业务领域。但OOP中的一个类主要是实践上的事情,而域模型就是方法论了。比如它可以指导类该如何设计。

DDD的好处

  DDD的目标是将较大的领域业务分解成更小、更易于管理的业务块,然后就可以分别对这些小的业务块建模。简单点来说DDD可以在业务的角度,指导如何对系统进行抽象。在软件设计中,抽象、概括的能力非常重要,可以说是低级程序员和高级程序员的分水岭。刚开始编程的时候,我觉得程序员就是用来实现业务的基本功能的,实现了就好了。随着后面技能的提升才发现,实现一个功能有很多种方法,但具体哪种才是一个最合适的方案呢?该如何选择呢?这个时候就需要一个方法论来指导系统的设计了。

DDD组件

  DDD提供了一组可以直接在代码中使用的工具,它们将是应用程序的构建块,这些构建块组合起来可以创建更大的软件系统。而这些构建块会成为确定actor正确结构的完美候选对象。因为二者都是比较独立的,高内聚低耦合!

域实体

  DDD使用实体的概念来引用系统中可由键或复合键唯一标志的对象。也就是说一个实体必须有一个唯一键,键不同则代表不同的实体,键相同则代表相同的实体。这跟数据库中含有主键的一行数据有点类似。实体可以包含可变的状态且唯一可识别的标志,可以直接映射成一个actor。

域值对象

  值对象在其包含的属性之外没有实体那样的标识,包含相同数据的两个值对象则认为是相同的。值对象是不可变的,值对象的任意数据改变了,则变成了两个不同的值对象。这跟scala中的case class有点相似。这跟actor之间传递的消息也一致。用于在actor之间传递的消息被称为消息协议。一个好的做法是将特定类型的actor消息嵌入到公共协议对象中。这个对象既可以是单个actor的伴生对象,也可以是单独的协议对象。其实Akka用的多了,你就会发现,完全是在面向协议编程。因为case class越来越多,也越来越重要,甚至可能比actor还重要。

聚合与聚合根

  聚合是应用程序内对象的集合。聚合创建了由系统中许多不同元素组成的逻辑分组,每个聚合都会被绑定到聚合根上。聚合根是聚合中的一个特殊实体,它负责管理该聚合中的其他成员。聚合的一个属性是禁止其他聚合对聚合中的任何内容持有引用。所以如果想访问聚合中的一些元素,必须通过聚合根,不能直接访问。聚合根是系统的顶层部分,所有与系统的交互将以某种方式与聚合根进行对接。当然了聚合根的设计并不是死的,而是要根据实际的业务进行划分,有时候还可能会改变。在Akka中,聚合根通常由父actor表示。

仓储

  仓储是开始抽象出基础架构问题的地方,他们可以在存储问题的上层创建一个抽象层。仓储的目的是从基础架构问题中抽象出抽象层,使用仓储的目标通常是从数据库或其他存储机制中重新构建聚合。当然在Akka中用一个actor来表示仓储也是非常自然和合理的。

工厂和对象创建

  工厂的主要作用是抽离出创建新的域对象时带来的复杂性。工厂和仓储的区别其实很小,工厂旨在抽象出新对象的创建,而仓储旨在抽象时对现有对象的重新创建。这一点大概可以用设计模式中的工厂设计模式来理解。

域服务

  服务是一个域对象,用来处理不适合作为聚合的操作,但服务可一个根据需要与聚合进行交互。在Akka中,服务可以是长期存在的actor,和其他聚合actor一起工作。或者可以是一个临时创建的actor,任务完成后就会终止。其实临时创建actor以完成某种任务,将会是一个非常适用的设计模式。

有界上下文

  DDD中有很多基础构建块,而有界上下文应该就是使其组合到一起对外提供服务的界限。有界上下文表示彼此隔离的服务。比如“账户”这个域对象,在不同的有界上下文中是不一样的,而有界上下文则是区分他们的一个方法、边界、标准。将应用程序分成单独的有界上下文并在多台机器上分发这些上下文的想法,其实就是分布式领域驱动设计(DDDD)的思想。

上一篇:AWS CloudFront CDN直接全站加速折腾记The request could not be satisfied. Bad request


下一篇:Java高新技术2--JAVA中枚举的各种应用以及单例模式