如何在Scala中处理POJO/JavaBean模式?

Jes*_*ose 16 scala

就像问题一样.scala是否像Java一样推广它?或者它已经演变成Scala的惯用语?或者它变得无关紧要了?

POJO和JavaBeans含义:

  1. 不带参数的构造函数
  2. 属性是私有的,getter和setter是公共的
  3. getter和setter定义属性,隐藏属性

此外,没有斯卡拉有意见(对不起,我不喜欢用这个词)上使用旧的public,private,protected属性的设计,是有关这个问题的?

Tom*_*icz 38

Scala也有类似POJO的习语,但它们与JavaBeans不同,Scala强调不同方面.

  1. Scala有不同的命名约定:

    def foo: Foo        //Foo getFoo() in Java
    def foo_=(foo: Foo)  //void setFoo(Foo foo) in Java
    
    Run Code Online (Sandbox Code Playgroud)

    这样您就可以随时写入obj.foo,obj.foo = bar即使您决定从getter/setter切换到直接字段访问,反之亦然.这称为统一访问原则.

  2. 由于Java互操作性,@BeanProperty引入了注释:

    @BeanProperty var foo: Foo = _
    
    Run Code Online (Sandbox Code Playgroud)

    上面的代码不仅创建了类似Scala的getter/setter,而且还创建了类似Java的代码,因此所有Java框架都可以无缝地工作.

  3. Scala强迫您在变量(var)和值(val)之间做出决定,因此您经常会发现自己使用不可变对象

  4. 我真的更喜欢构造函数中的不可变对象和初始化,这在Scala中非常容易:

    class Foo(val age: Int, val name: String)
    
    Run Code Online (Sandbox Code Playgroud)

    甚至(val默认在case类中):

    case class Foo(age: Int, name: String)
    
    Run Code Online (Sandbox Code Playgroud)

    这段代码简洁明了.但是,如果您需要与Java框架合作,您仍然需要no-argu构造函数和setter:

    public class Foo(var age: Int, var name: String) {
    
        def this() {
            this(0, "")
        }
    
    }
    
    Run Code Online (Sandbox Code Playgroud)

    注意val被替换为var.

  5. 与Java相比,Scala中的访问修饰符具有稍好的默认值:

    class Foo(var a: Int, x: Int) {
    
        var b: Int = _
    
        private var c: Int = _
    
        private[this] var d: Int = _
    
        def twisted = a + b + c + d + x
    
    }
    
    Run Code Online (Sandbox Code Playgroud)

    变量ab将成为private与领域publicgetter/setter方法(字段默认私有的,方法是公开的).c并且d也是私有变量.但额外的private[this]品牌d是直接访问内部类中的,而不是私人的getter/setter.

    因为x在构造函数旁边的某处使用,Scala也会自动为它创建私有字段.但是没有生成getter/setter,它可以直接在twisted方法中访问(与之相同d).

更新:在评论中,您要求重命名getter/setter.这是更复杂的例子.Getters/setter同时根据两个字段计算值:

class Foo {

    private[this] var first: Char = _
    private[this] var rest: String = _

    def fake = first + rest

    def fake_=(s: String) {
        first = s.head
        rest = s.tail
    }

}
Run Code Online (Sandbox Code Playgroud)

内部看起来很复杂,但从外面看起来它看起来很古老:

val foo = new Foo()
foo.fake = "ABC"
println(foo.fake)
Run Code Online (Sandbox Code Playgroud)

就像它是:

class Foo(var fake: String)
Run Code Online (Sandbox Code Playgroud)

  • 你在8分钟内写完了吗?这很棒!:d (4认同)