在Akka的case类中应该是什么类型的属性

时间:2015-08-06 09:38:39

标签: scala akka actor

我正在使用Scala 2.11.1和akka 2.3.8

假设我有一个班级

case class Person(firstName : String, var  lastName : String,var age : Int, doB : DateTime)

我很困惑,我应该将val用于所有属性,还是应该为var寻找可以在将来变异的属性

请指导我做什么更好的方法,记住我在演员消息传递中使用此类的对象

编辑:

另外请告诉我一个线程是否来了并更改了该类的属性,这是一个到位突变还是一个新的对象将与更改的属性一起形成?

2 个答案:

答案 0 :(得分:2)

首先,我认为在这种情况下你不应该同时拥有agedoB。你在寻找麻烦。仅使用doB并在需要时计算年龄,价格便宜。对于初学者来说,doB是不变的,年龄会发生变化。这是域名,与Scala或Akka无关。此外,由于这是一个消息,Data Transfer Object,它不应该有变异的需要,它没有很长的生命周期,恕我直言。

这可能解决了你的具体问题,但一般情况下,如果你真的需要变异,那么请将其设为var。但又一次,考虑一下你是否需要它。如果您需要更改它,那么创建一个setter,它创建一个新的,也是不可变的对象,具有与前一个相同的属性,但更改了一个属性。

编辑:

由于您向问题添加了详细信息,可能需要一些其他说明。

如果您正确使用Akka,则不必担心线程会更改对象。每个actor都是一个独立的线程,它拥有自己独立的范围。这意味着从ActorA发送到ActorB的邮件是副本。在ActorB中更改邮件不会更改ActorA范围内的任何数据。请记住,演员应该只根据他们收到的消息做出反应。一个活动,不应该干扰另一个,考虑到他们不共享资源,如数据库,这是另一个故事。

@ccheneson通过编辑一些属性来解释如何从现有对象创建新的不可变对象。使用copy方法时,您会获得两个对象,您复制的原始对象(未更改)和新修改的对象。如果你这样做,例如:

val p1 = Person("Aleksandar","Stojadinovic",25,"1970-01-01") //mocking the date, ignoring I advised you not to use age, and look what I was allowed to do ^.^
p1.age=28
println(p1.age) //outputs 28

您的p1现已更改。如果您使用常规线程而不是Akka,则可能会遇到线程同步和Reader-Writer problem

的问题

如果你正在尝试,那么你不应该在一个actor中运行线程。

答案 1 :(得分:1)

Aleksandar Stojadinovic对agedoB有一个很好的观点。

我只想补充一点,您可以将所有属性保留为val,如果需要更改属性值,请使用copy方法(随case class免费提供)并更改所需的属性。 copy将返回一个新的Person对象,其中您的属性已更新

scala> case class Person(firstname: String, lastname:String)
defined class Person

scala> val p1 = Person("John", "Doe")
p1: Person = Person(John,Doe)

scala> val p2 = p1.copy(lastname = "Wayne")
p2: Person = Person(John,Wayne)