加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 功能编程领域驱动的设计

发布时间:2020-12-16 09:21:07 所属栏目:安全 来源:网络整理
导读:功能编程促进不变类和参照透明度. 域驱动设计由Value Object(不可变)和Entities(可变)组成. 我们应该创建不变的实体,而不是可变的实体吗? 我们假设项目使用Scala作为主要语言,如果我们处理并发,我们如何将Entities作为案例类(不可变的)编写,而不会有陈旧的
功能编程促进不变类和参照透明度.

域驱动设计由Value Object(不可变)和Entities(可变)组成.

我们应该创建不变的实体,而不是可变的实体吗?

我们假设项目使用Scala作为主要语言,如果我们处理并发,我们如何将Entities作为案例类(不可变的)编写,而不会有陈旧的状态风险?

什么是好习惯?保持实体可变(var fields etc …),并避免case类的很好的语法?

解决方法

您可以有效地使用Scala中的不可变实体,并避免可变字段的恐怖以及源自可变状态的所有错误.使用Immutable实体可以帮助您并发,不会使事情变得更糟.您以前的可变状态将成为一组转换,将在每次更改时创建一个新的参考.

然而,在您的应用程序的某一级别,您将需要具有可变状态,否则您的应用程序将无用.这个想法是在程序逻辑中尽可能地推动它.举一个银行帐户的例子,可以因利率和ATM取款而改变
存款.

你有两种有效的方法:

>您公开可以修改内部属性的方法,并且在这些方法上管理并发性(实际上很少)
>你让所有的课程都不可变,你可以用一个“经理”来改变这个账户.

由于第一个是非常简单的,我会详细说明第一个.

case class BankAccount(val balance:Double,val code:Int)

class BankAccountRef(private var bankAccount:BankAccount){
   def withdraw(withdrawal) = {
       bankAccount = bankAccount.copy(balance = bankAccount.balance - withdrawal)
       bankAccount.balance
   }
}

这是很好的,但天啊,你仍然坚持管理并发.那么,Scala为您提供了一个解决方案.这里的问题是,如果您将BankAccountRef的引用与您的后台作业分享,则必须同步该呼叫.问题在于您以次优的方式执行并发.

执行并发的最佳方式:消息传递

如果在另一方面,不同的工作不能直接在BankAccount或BankAccountRef上调用方法,而只是通知他们有些操作需要执行?那么那么你有一个Actor,在Scala中最好的并发方式.

class BankAccountActor(private var bankAccount:BankAccount) extends Actor {

    def receive {
        case BalanceRequest => sender ! Balance(bankAccount.balance)
        case Withdraw(amount) => {
            this.bankAccount = bankAccount.copy(balance = bankAccount.balance - amount)
        }
        case Deposit(amount) => {
            this.bankAccount = bankAccount.copy(balance = bankAccount.balance + amount)

        }

    }
}

该解决方案在Akka文档:http://doc.akka.io/docs/akka/2.1.0/scala/actors.html中进行了广泛的描述.这个想法是通过向邮箱发送消息来与Actor进行通信,这些消息按照接收的顺序进行处理.因此,如果使用此模型,您将永远不会有并发的缺陷.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读