面向数据编程 Data-Oriented Programming [20]
2021/6/20 11:49:59
本文主要是介绍面向数据编程 Data-Oriented Programming [20],对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
4.4 数据安全
你:关于结构性分享的事情,我有些不清楚。如果我们编写代码来修改在两个版本的数据之间共享的数据部分,会发生什么情况?更改是否会影响两个版本?
乔:你能不能写一段代码来说明你的问题?
你开始在笔记本电脑上键入内容,然后就会出现清单4.4中的代码片段,它说明了你的观点。
清单4.4 修改两个版本之间共享的数据的一段代码
var member = { "email": "joe@me.com", "password": "secret", "isBlocked": true } var updatedMember = _.set(member, "password", "hidden"); member["isBlocked"] = false;
你:我的问题是:updatedMember中isBlocked的值是什么?
乔: 答案是:禁止通过本地哈希图设置器来改变数据。所有的数据操作都必须通过不可变的函数。
警告 所有的数据操作都必须通过不可变的函数完成。严禁使用本地Hash Map setter。
你:当你说禁止时,你的意思是由developer来确保它不会发生。对吗?
乔:没错。
你:有什么办法可以保护我们的系统不受开发者的错误影响?
乔: 是的,有一种方法可以在数据结构的层面上确保数据的不可更改性。这就是所谓的持久性数据结构。
你:持久性数据结构在内存和计算方面是否也很高效?
乔: 实际上,持久性数据结构内的数据组织方式使它们比不可变的函数更有效率。
TIP 持久性数据结构在数据层面是不可改变的。没有办法改变它们(即使是错误的操作)。
你:是否有提供持久性数据结构的库?
乔:当然有。例如,我们有JavaScript中的Immutable.js,Java中的 Paguro,C#中的Immutable Collections ,Python中的Pyrsistent,Ruby中的Hamster
您:那么为什么不使用持久数据结构而不是不可变函数呢?
乔:持久数据结构的缺点是它们不是本机的,这意味着使用它们需要从本机到持久以及从持久到本机的转换。
你:那你推荐哪种方式呢?
乔:如果你想玩一玩,那就从不可变函数开始吧。但是对于生产应用程序,我建议使用持久数据结构。
你:所以糟糕的原生数据结构不是持久的!
乔:这是我喜欢Clojure的原因之一:该语言的原生数据结构是不变的!
4.5 突变的提交阶段
到目前为止,我们已经了解了如何实现变异的计算阶段。计算阶段是无状态的,因为它不会对系统进行任何更改。现在,我们将了解如何在提交阶段更新系统状态。
再看一下清单4.5中Library.addMember()的代码,您会发现一些问题:该函数返回库的一个新状态,其中包含一个额外的成员,但它不影响库的当前状态!
清单4.5 变异的计算阶段不会对系统进行任何更改
Library.addMember = function(library, member) { var currentUserManagement = _.get(library, "userManagement"); var nextUserManagement = UserManagement.addMember(currentUserManagement, member); var nextLibrary = _.set(library, "userManagement", nextUserManagement); return nextLibrary; };
你:我看到Library.addMember()没有改变库的状态。那么,库状态是如何更新的呢?
乔:这是个很好的问题。AddMember()只处理数据计算,并且是无状态的。在提交阶段,通过向前移动系统状态引用的状态版本来更新状态。
你:什么意思?
乔:这是我们向系统添加会员时会发生的情况。计算阶段创建具有两个会员的状态版本。在提交阶段之前,系统状态是指具有一个会员的状态版本。提交阶段的职责是将系统状态向前移动,以便它引用具有两个会员的状态版本。
图4.5 提交阶段向前移动到系统状态TIP 提交阶段的职责是将系统状态前进到计算阶段返回的状态版本。
你:就代码而言,它看起来怎么样?
乔:代码由两个类组成:System,一个实现突变的单例有状态类。SystemState管理系统状态的单个有状态类。
你:在我看来,这听起来像是典型的面向对象。
乔:对。系统的这一部分是有状态的,非常类似于OO。
你:我很高兴看到你仍然在OO中发现了一些有用的东西。
乔:冥想教会了我,我们宇宙的每一块都有自己要扮演的角色。
你:好极了!你能给我看一些代码吗?
乔:当然可以。让我们从System类开始:清单4.6显示了addMember突变的实现。
清单4.6 系统类
class System { addMember(member) { var previous = SystemState.get(); var next = Library.addMember(previous, member); SystemState.commit(previous, next); } }
你:SystemState是什么样子的?
乔:清单4.7显示了SystemState类的代码:它是一个有状态类!
清单4.7 SystemState类
class SystemState { systemState; get() { return this.systemState; } commit(previous, next) { this.systemState = next; } }
你:我不明白SystemState的意思。这是一个具有getter和Commit函数的简单类!
乔:稍后,我们将丰富SystemState.Commit()方法的代码,以便它提供数据验证和历史跟踪。目前,需要注意的重要一点是,计算阶段的代码是无状态的,并且它与提交阶段的有状态代码是分离的。
TIP 计算阶段是无状态的。提交阶段是有状态的。
这篇关于面向数据编程 Data-Oriented Programming [20]的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南