何时使用领域驱动设计 (2)

有了领域对象,自然就需要管理对象的生命周期,在介绍工厂和仓储之前,先看一下与领域对象相关的两个抽象概念:聚合与聚合根。聚合是能够表达一个完整的领域概念(或者说业务概念)的实体和值对象的组合,如果用UML类图来表示聚合,应该选择使用组合模式。不难理解,聚合里的所有实体和值对象都有相同的生命周期,它们被同时创建,也被同时销毁。对于每一个聚合,必定有一个实体其本身就代表了整个聚合的业务意义,比如“销售订单”聚合可以由“销售订单”实体、“销售订单明细”实体以及“联系地址”值对象组成,而其中的“销售订单”实体就代表了整个聚合的业务意义,像这样的实体,我们称之为聚合根。当然,有些聚合仅包含一个实体,而这个聚合的聚合根就是这个实体本身。所有与生命周期相关的操作都应该发生在聚合根上。 在领域驱动设计中,工厂负责创建聚合,而仓储负责聚合的持久化、激活以及销毁,这些操作都是应用在聚合根上。同样,领域驱动设计并没有讨论工厂和仓储应该如何实现,然而基于它们本身的特点,在实际中我们更多地会选择一些创建型模式来实现工厂,而选择一些数据持久化机制(比如数据库)来实现仓储。就仓储的实现而言,我们基本上会结合底层的数据存储技术选型来决定仓储的设计,甚至会将其抽象成仓储设计模式。在不同的架构风格下,仓储的职责也会有所不同:传统分层架构下,仓储是有查询职责的,因为它需要基于聚合根来重建整个聚合,然而,在基于事件的CQRS架构中,仓储的查询职责变得非常薄弱,这是由于读写分离造成的。 以上基本上对领域驱动设计的基础性内容进行了回顾,如果你的项目正在,或者将要遵循上面的这些概念和指引进行业务分析与领域建模,或者在进行需求分析的时候,你的团队也在不停地考虑如何在软件中设计你所要面对的这些业务对象,并且在不停地梳理相关的领域知识,那么恭喜你,你已经步入了领域驱动设计的正轨。当然,在领域模型建立的过程中,你会发现很多问题,比如你会发现,银行账户与互联网登录账户都叫“账户”,但它们却是完全不同的东西;你甚至会发现,虽然都是“银行账户”,但在不同的场景下它所表述的意义完全不同(例如用于支付的支付账户与用户的定期账户是两码事),对于这些问题,领域驱动设计也提出了相应的解决方案,比如引入“界定上下文(Bounded Context)”的概念,而这一概念也刚好契合了目前最流行的软件架构风格:微服务架构风格,下文再深入讨论。 接下来你可以考虑本文刚开始的问题:我应该选择什么样的架构风格来构建我的系统。

软件系统架构风格

通常情况下,我们会选择一种软件架构风格来实现软件系统,而在开发的过程中,我们还会应用很多开发模式并且引入一些开发方法论,比如在模型持久化部分,我们会选择仓储模式,而在构建领域对象模型时,又有可能用到访问者模式,我们还会选择使用敏捷开发方法论来指导我们的日常开发任务等等。由此可见,软件系统架构风格并非是一种模式,简单地说,架构风格决定了系统将由哪些组件组成,以及这些组件之间的关系如何,而架构模式则表述了如何实现这些组件以及处理它们之间的关系。 在《面向模式的软件体系结构(卷一):模式系统》一书中,将软件设计模式分为三种:体系结构模式设计模式以及惯用法。体系结构模式也就是架构模式,常见的有黑板模式、分层模式、MVC、发布者/订阅者、Proactor/Reactor、命令查询职责分离(CQRS)等等。这些模式的共同特点是,它们对软件系统的基本组织进行描述,这包括各种组件以及组件之间、组件与环境之间的相互关系的定义,并决定了软件系统设计与演进的原则。设计模式更多的是在组件内部,对于对象及其之间的关系以及它们之间的行为与协作提供一定的设计准则,从而使得组件的设计满足面向对象的SOLID原则。惯用法则是与特定编程语言相关的一种常用模式,比如在C#中,对于单例模式(Singleton)有它自己的独特的实现方式,这种方式依赖于C#中静态字段是线程安全的语言特性,而这种实现方式却并不能用在C++中。 与架构模式相比,架构风格并不关心真正的业务领域是什么,以及软件系统需要解决什么样的业务问题。无论你是开发ERP系统,还是开发购物网站,你都可以选择微服务架构,只是不同领域所需要的微服务不同罢了。常见的软件系统架构风格有:经典分层架构(N-Tier)、事件驱动架构(EDA)以及微服务架构(Microservices)。随着云计算的普及和推进,也衍生出了一些与云计算、人工智能以及大数据处理相关的架构风格,比如基于微软Azure云平台的Web-Queue-Worker架构、Big data架构以及Big Compute架构。那么,我到底应该选择什么样的架构风格呢?在不同的架构风格下,领域驱动设计又如何运用呢?下面就对比较常见和流行的经典分层架构、事件驱动架构以及微服务架构做一些介绍。

经典分层架构(N-Tier Architecture)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zysxxd.html