面向数据编程 Data-Oriented Programming [12]

2.4 代码模块

  DO设计过程的第二步是定义系统的代码模块。

乔:既然您已经确定了系统的数据实体,并将它们分组到高级组中,那么是时候考虑一下系统的代码部分了。

你:你说的代码部分是什么意思?

乔:考虑这个问题的一种方式是确定你的系统的功能。

你将再次查看Nancy的需求餐巾纸,这一次您将突出显示代表系统功能的动词短语:

旁白
突出显示需求中与功能相对应的术语

  • 两类用户:管理员和会员
  • 用户通过电子邮件和密码登录系统。
  • 会员可以借书
  • 会员和图书管理员可以按书名或作者搜索图书
  • 图书馆员可以屏蔽和解锁会员(例如,当他们还书迟到时)
  • 图书馆员可以列出会员目前借出的书籍
  • 一本书可能有好几本

  除此之外,显然会员还可以退还一本书。此外,应该有一种方法来检测用户是否是图书管理员。
  您写下系统的功能列表。

旁白
系统的功能

  1. 搜索一本书。
  2. 添加图书项目。
  3. 阻止成员。
  4. 取消阻止成员。
  5. 将用户登录到系统。
  6. 列出会员目前借出的书籍。
  7. 借书。
  8. 归还一本书。
  9. 检查用户是否为图书管理员

乔:太棒了!现在,告诉我哪些功能需要向外界公开?

你:你说暴露在外面是什么意思?

乔:假设图书馆管理系统通过HTTP公开了一个API:API的端点是什么?

你:我明白了。除了检查用户是否是图书馆员之外,它们的所有功能都应该公开。

乔:太好了,现在给每个公开的功能起一个简短的名称,然后把它们集合到一个叫做Library的模块里

  所需时间不到一分钟:图2.3显示了包含库公开函数的模块框。

图2.3图书馆模块包含图书馆管理系统暴露的功能

 

TIP 设计DO系统的代码部分的第一步是将公开的函数聚合到单个模块中。

乔:太漂亮了。您刚刚创建了第一个代码模块。

你:在我看来,它就像一个类:模块和类有什么不同?

乔:模块是功能的集合。在面向对象中,模块由类表示,但在其他编程语言中,它可能是包或命名空间。

你:我明白了。

乔:DO代码模块的重要之处在于它们只包含无状态函数。

你:你是说像Java中的静态方法?

乔:没错!

你:那么这些函数是如何知道它们对哪些信息进行操作的呢?

乔:我们把它作为第一个参数传递给函数。

你:我不明白。你能给我举个例子吗?

乔查看了图2.3中的Library模块的函数列表。

乔:让我们以getBookLendings()为例:在经典的OO中,它的参数是什么?

你:一个图书管理员ID和一个会员ID。

乔:在传统的OO中,getBookLendings是一个接受两个参数的Library类的方法:LibrarianId和MemberId

你:是的。

乔:现在来看微妙的部分:在DO中,getBookLendings是库模块的一部分,除了其他参数外,它还接收LibraryData作为第一个参数。

你:你能告诉我你的意思吗?

乔:当然可以。

乔走近你的键盘,开始打字。
这就是OO中类方法的外观:

class Library {
	libraryData // state of the object
	getBookLendings(userId, memberId) {
		// accesses library data via this.libraryData
	}
}

  该方法通过this.library访问对象的状态-在我们的例子中是libraryData。对象的状态是对象方法的隐式参数。

TIP 在经典的OO中,对象的状态是对象方法的隐式参数。

  在DO中,getBookLendings的签名如下所示:

class Library {
	static getBookLendings(libraryData, userId, memberId) {
	}
}

  Library 的状态存储在Library类外部管理的LibraryData中,LibraryData作为显式参数传递给getBookLendings静态方法。

TIP 在DO中,代码模块的函数是无状态的:它们接收作为显式参数(通常是第一个参数)操作的数据。

  同样的规则也适用于 Library 模块的其他函数。它们都是无状态的:它们接收库数据作为第一个参数。

重点 模块是功能的聚合。在DO中,模块函数是无状态的。

  您可以应用此规则,并通过包含有关函数参数的详细信息来优化库模块的设计。

图2.4带有函数参数的库模块

 
乔:太好了。现在,我们已经准备好在高层次上设计我们的系统。

你:什么是DO中的高层次设计?

乔:模块的定义以及它们之间的交互。

你:我明白了。有什么指导原则可以帮助我定义模块吗?

乔:当然可以。系统的高级模块对应于高级数据实体。

你:你是说出现在数据思维导图中的数据实体吗?

乔:没错!

  再次查看图2.5中的数据思维导图,您将重点放在高级数据实体上:Library, Catalog 和 User management.

图2.5 图书馆管理系统高级数据实体思维导图

 
  这意味着在系统中,除了图书馆模块之外,我们还有两个高级模块:

  1. 处理目录数据的Catalog模块
  2. UserManagement 模块,处理用户管理数据

  然后通过添加Catalog和UserManagement模块,画出图书管理系统的总体设计:

  • Catalog的函数将CatalogData作为第一个参数接收
  • UserManagement的函数接收userManagementData作为第一个参数

图表如下:

图2.6 带函数参数的图书馆管理系统模块

 
  您可能还不清楚数据实体是如何在模块之间传递的。目前,您可以将LibraryData看作有两个成员的类:

  • 保存目录数据的catalog
  • 保存用户管理数据的userManagement

  图书馆的功能有一个共同的模式:

  1. 它们将libraryData作为参数接收
  2. 它们将LibraryData.Catalog传递给Catalog函数
  3. 它们将LibraryData.userManagement传递给UserManagement的函数

  稍后,在本章中,我们将看到库模块的一些函数的代码。

TIP DO系统的高级模块对应于高级数据实体。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值