原创 | 使用 JPA 实现 DDD 持久化 -O 与 R: 两个世界

用户头像
编程道与术
关注
发布于: 2020 年 08 月 03 日
原创 | 使用JPA实现DDD持久化-O与R:两个世界

自有编程语言以来,一共出现过三种编程范式:结构化编程(Structured Programming)、面向对象编程(Object-oriented Programming)和函数式编程(Functional Programming)。结构化编程已经是明日黄花,函数式编程是后起之秀,而面向对象编程范式仍然是当今占统治地位的编程范式。在现在仍然活着的编程语言中,除了C语言还是采用结构化编程范式之外,绝大多数都是采用面向对象的编程范式,包括广为流行的Java、C#,C++,Swift,Kotlin、Scala等等(部分语言在面向对象之外,也加入了函数式编程支持)。



任何企业软件的核心都是业务逻辑的组织和实现。Martin Fowler在著名的《企业应用架构模式》一书中对于业务逻辑的组织提出了四种模式:Transaction Script(事务脚本),Table Module(表模块),Active Record(活动记录)及Domain Model(领域模型)。事务脚本是面向过程的,表模块和活动记录是面向数据的,而领域模型是面向对象的。如果使用面向对象的编程语言来编写程序的话,采纳面向对象的领域模型来组织和实现业务逻辑无疑是最佳选择。



面向对象的企业应用以领域模型而不是数据模型为核心进行分析、设计和实现。领域模型中的领域对象——包括各种实体和值对象——持有企业数据并实现业务逻辑。面向对象的核心特征是继承、封装和多态,而对象之间可以有依赖、关联、泛化、聚合和组合等关系,领域模型支持所有这些特征和关系。



如果运行企业应用的服务器内存无限大而且永不停机,理论上我们就只需要以面向对象的编程语言编写的程序,而不需要任何形式的数据库。所有的数据都由程序中的对象以字段值的形式持有,并可以通过调用对象上的方法获得这些数据。但是,由于以下一些重要原因,我们还是需要一个数据库来存储业务数据:



  • 服务器内存不可能无限大。想象你在营运一个全球性的大电商系统,每日产生数亿条订单数据,而且系统需要保存几年甚至几十年的历史数据,你不太可能拥有这么大的内存来存放这么巨大的数据量,即使有,其成本也会是个天文数字。



  • 服务器不太可能永不停机。系统运行中可能会出现故障(停电,死机等等),在应用程序的生命周期中还会有很多次的维护和升级,所有这些都会不可避免地导致电脑停机重启。一旦停机,内存中的一切数据都会永久丢失,这对于企业来说是致命的。



  • 需要和其他应用共享数据。假设我们目前在运行的是一个电商程序,产生了大量的订单数据。为了统计成果,发现趋势,我们往往还需要再建设一个大数据分析应用,来分析电商系统产生的数据。让电商应用直接向大数据应用推送数据或者让大数据应用访问电商应用获取数据都是不合理的设计(造成非常不合理的耦合),以一个标准化的、编程语言无关的数据库形式共享数据才是最合理的设计。



  • 服务器集群的需要。为了实现高并发、高可用的目标,我们往往会启动应用服务器集群,每台服务器都是对等的,共同为所有的客户服务。这样一来,单独在应用服务器的内存中存储业务数据就是不可行的,也是应该在某种形式的数据库中存储业务数据,供所有的应用服务器共享访问。



因此,我们必然需要将应用程序中的数据持久化到某种形式的数据库中,以节省内存,并在服务器重启后将数据恢复到内存中,同时提供给集群的应用服务器和第三方应用进行共享访问。



按理说,面向对象的编程语言只有和面向对象的数据库才能配合无间。但现实是:虽然目前有一些面向对象的数据库系统,但都远没有达到成熟可用的程度,目前占统治地位的仍然是关系数据库系统。因此,至少在目前以及可预见的将来,前端的面向对象的编程语言与后端的关系数据库仍然是最优组合。但是对象模型和关系模型是根据不同的理论,面向不同的意图设计的,两者在很多方面方凿圆枘,并不适配,这就是所谓的对象-关系阻抗失配(object/relational impedance mismatch)。为了让两者适配,我们需要编写相应的转换代码,在对象模型和关系模型之间进行双向映射。

Java Persistence API,简称JPA,是一个官方的对象/关系映射(Object/Relational Mapping,简称ORM )规范,它能够在对象模型和关系模型之间进行双向转换,目的是解决对象-关系阻抗失配问题,使面向对象的领域模型与面向关系的数据模型能够和谐共处。Hibernate是JPA规范的一个实现。我们可以针对JPA规范进行编程,而将Hibernate隐藏在幕后,负责在运行时执行真正的对象关系映射操作。



详细内容请戳这里↓↓↓

原创 | 使用JPA实现DDD持久化-O与R:两个世界



这一节就讲到这里,下一节我们讲讲"O:对象的世界"



如果觉得有收获,点个【赞】鼓励一下呗!



发布于: 2020 年 08 月 03 日 阅读数: 27
用户头像

编程道与术

关注

高级架构师,技术顾问,交流公号:编程道与术 2020.04.28 加入

杨宇于2020年创立编程道与术,致力于研究领域分析与建模、测试驱动开发、架构设计、自动化构建和持续集成、敏捷开发方法论、微服务、云计算等顶尖技术领域。 了解更多公众号:编程道与术

评论

发布
暂无评论
原创 | 使用JPA实现DDD持久化-O与R:两个世界