Подтвердить что ты не робот

Как обрабатывается шаблон POJO/JavaBean в Scala?

Как и вопрос. Поддерживает ли scala так же, как Java? Или было ли развито более идиоматично для Scala? Или это было сделано неуместным?

POJO и JavaBeans означают:

  • Конструктор, который не принимает параметров
  • атрибуты являются частными, getters и seters являются общедоступными.
  • getters и seters определяют свойства, скрывающие атрибуты

Кроме того, имеет ли scala мнение (извините, мне не нравится этот термин) при использовании старых конструкций атрибутов public, private, protected, которые имеют отношение к этому вопросу?

4b9b3361

Ответ 1

Scala также имеет POJO-подобные идиомы, но они отличаются от JavaBeans, а Scala делает упор на различные аспекты.

  • Scala имеет различные соглашения об именах:

    def foo: Foo        //Foo getFoo() in Java
    def foo_=(foo: Foo)  //void setFoo(Foo foo) in Java
    

    Таким образом, вы всегда можете писать obj.foo и obj.foo = bar, даже если вы решили переключиться с геттеров/сеттеров на прямой доступ к полям и наоборот. Это называется принципом единого доступа.

  • Благодаря функциональности Java, была введена аннотация @BeanProperty:

    @BeanProperty var foo: Foo = _
    

    приведенный выше код не только создает Scala -пользователи getters/seters, но также и Java-подобные, поэтому все фреймворки Java работают без проблем.

  • Scala заставляет вас выбирать между переменными (var) и значениями (val), поэтому вы обнаруживаете себя гораздо чаще с помощью неизменяемых объектов

  • Я действительно предпочитаю неизменные объекты и инициализацию в конструкторе, который был очень упрощен в Scala:

    class Foo(val age: Int, val name: String)
    

    или даже (val по умолчанию в классах case):

    case class Foo(age: Int, name: String)
    

    Этот фрагмент кода является блестящим по своей простоте. Однако, если вам нужно сотрудничать с фреймворками Java, вам все равно не нужны конструкторы и сеттеры no-arg:

    public class Foo(var age: Int, var name: String) {
    
        def this() {
            this(0, "")
        }
    
    }
    

    Примечание val заменяется на var.

  • Модификаторы доступа в Scala имеют несколько более высокие значения по умолчанию по сравнению с Java:

    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
    
    }
    

    Переменные a и b станут private полями с public getters/seters (поля являются закрытыми по умолчанию, методы общедоступны). c и d также являются частными. Но дополнительный private[this] делает доступным d непосредственно внутри класса, а не частным получателем/установщиком.

    Поскольку x используется где-то рядом с конструктором, Scala автоматически создает для него собственное поле. Однако не создаются геттеры/сеттеры, к ним обращаются непосредственно в методе twisted (так же, как d).

UPDATE: в комментариях вы спрашиваете о переименовании получателей/сеттеров. Вот еще более сложный пример. Getters/seters вычисляют значение на основе двух полей одновременно:

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
    }

}

Сложно усложняется внутри, но со стороны это выглядит как старое свойство:

val foo = new Foo()
foo.fake = "ABC"
println(foo.fake)

Так же, как если бы это было:

class Foo(var fake: String)