通过将代码与数据分离来降低系统复杂性
2.1简介
正如我们在第0章中提到的,面向数据编程(DO)的最大洞察力在于,我们可以通过将代码与数据分开来降低系统的复杂性。事实上,当代码与数据分离时,我们的系统由两个可以分开考虑的主要部分组成:数据实体和代码模块。
本章深入探讨了面向数据编程的第一个原则:
NOTE 原则#1:以代码驻留在函数中的方式将代码与数据分开,这些函数的行为不依赖于以某种方式封装在函数上下文中的数据。
我们在第1章介绍的图书馆管理系统的上下文中说明了代码和数据的分离,并揭示了这种分离给系统带来的好处:
- 系统简单易懂
- 该系统非常灵活:通常情况下,它不需要更改设计来适应不断变化的需求
我们将展示如何:
- 设计代码与数据分离的系统
- 编写遵守代码和数据分离的代码。
本章重点介绍代码和数据分开的系统的代码部分的设计。在第三章中,我们将重点介绍系统的数据部分的设计。随着本书的进展,我们将发现将代码与数据分离的其他好处。
2.2 DO系统的两个部分
在您的朋友中快速搜索一下可以教您的DO专家,就会找到Joe,他是一名40岁的开发人员,曾是一名Java开发人员多年,7年前搬到了Clojure。
你决定聘请乔在你的办公室举办1对1的研讨会。
当你告诉乔你建立的图书馆管理系统(第一章)以及你为适应不断变化的需求而进行的斗争的细节时,他并不感到惊讶。
Joe告诉你,他和他的团队在过去7年里用Clojure构建的系统比他以前用Java构建的系统更不复杂、更灵活。造成这种好处的主要原因是,他建立的系统是遵循面向数据编程的原则。
你:“是什么让DO系统变得不那么复杂,更加灵活?”
乔:“DO的第一个洞察力是关于代码和数据之间的关系。”
你:“你是说数据在对象中的封装?”
乔:实际上,DO是反对封装的。
你:“这是为什么?我以为封装是一种积极的编程范式。”
乔:“数据封装有其优点和缺点。想一想你设计图书馆管理系统的方式(在第一章)。根据DO的说法,系统的复杂性和缺乏灵活性的主要原因是代码和数据混在一起(在对象中)。”
TIP DO是反对数据封装的
你:“这是否意味着,为了坚持DO,我需要摆脱OO,学习函数式编程语言?”
乔:“不。DO原则与语言无关:它们既可以应用于OO语言,也可以应用于FP语言。”
你:“酷!我担心你要教我关于一元数、代数数据类型和高阶函数的知识。”
乔:“这些都不是DO所必需的。”
TIP DO原则是无关语言的。
你:“在DO中,代码和数据的分离看起来怎么样?”
乔:“数据由仅包含成员的数据实体表示。代码被聚合到模块中,其中所有函数都是无状态的。”
你:“你说的无状态功能是什么意思?”
乔:“不是将状态封装在对象中,而是将数据实体作为参数传递。”
你:“我不明白。”
乔:“让我把它变得直观些。”
你:“还不够清楚”
乔:“当我向你展示它在你的图书馆管理系统中是什么样子的时候,事情就会变得更清楚了。”
你:“好的。我们是从编码开始还是从数据开始?”
乔:“嗯,这是面向数据的编程。让我们从数据开始吧!”
2.3 数据实体
在DO中,我们从发现系统的数据实体开始设计过程。
乔:“你们系统的数据实体是什么?”
你:“你说的数据实体是什么意思?”
乔:“我是说你的系统中保存信息的部分。”
NOTE 数据实体是系统中保存信息的部分
你:“嗯,这是一个图书馆管理系统,所以我们肯定有书和会员”
乔:“当然可以。但是还有更多:发现系统数据实体的一种方法是在系统需求中查找名词和名词短语。”
您可以查看Nancy的需求餐巾纸,并突出显示似乎代表系统数据实体的名词和名词短语:
旁白
突出显示需求中与数据实体相对应的术语
- 两类用户:图书馆管理员和图书馆会员
- 用户通过电子邮件和密码登录系统。
- 会员可以借书
- 会员和图书管理员可以按书名或作者搜索图书
- 图书馆员可以屏蔽和解锁会员(例如,当他们还书迟到时)
- 图书馆员可以列出会员目前借出的书籍
- 一本书可能有好几本
乔:“太好了。你能看到一种对实体进行分组的自然方式吗?”
你:“不确定,但在我看来,用户、会员和图书管理员是一个群体,而图书、作者和书本则是另一个群体。”
乔:“我觉得不错。你怎么调用每个小组?”
您:“第一组的用 User Management ,第二组的用Catalog。”
旁白
组织在嵌套列表中的系统数据实体
Catalog数据
- Data about books
- Data about authors
- Data about book items
- Data about book lendings
User Management 数据
- Data about users
- Data about members
- Data about librarians
你:“我不太清楚书和作者之间的关系,应该是联合还是组成?”
乔:“暂时不要太担心细节。我们稍后将改进我们的数据实体设计(第3章)。现在,让我们在思维导图中想象一下这两个群体。”
可视化DO系统的数据实体最精确的方法是用不同的箭头绘制数据实体图,以进行关联和组合。我们将在第三章回到数据实体图。
TIP 发现系统的数据实体,并将它们分组到高级组中,可以是嵌套列表,也可以是思维导图。
我们将在第三章更深入地研究数据实体的设计和表示。现在,让我们简化一下,假设我们的图书馆系统的数据由两个高级组组成:用户管理组和目录组。