Как обрабатывается паттерн POJO / JavaBean в Scala? - PullRequest
14 голосов
/ 12 марта 2012

Так же, как вопрос. Скала продвигает это так же, как Java? Или он стал более идиоматичным по отношению к Scala? Или это было сделано неактуальным?

POJO и JavaBeans, означающие:

  1. Конструктор, который не принимает параметров
  2. атрибуты являются частными, методы получения и установки являются общими
  3. геттеры и сеттеры определяют свойства, скрывая атрибуты

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

1 Ответ

37 голосов
/ 12 марта 2012

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

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

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

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

  2. В связи с совместимостью с Java введена аннотация @BeanProperty:

    @BeanProperty var foo: Foo = _
    

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

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

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

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

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

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

    Этот фрагмент кода великолепен своей простотой.Тем не менее, если вам нужно взаимодействовать с Java-фреймворками, вам все равно нужны не требующий аргументов конструктор и сеттеры:

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

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

  5. Модификаторы доступа в 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 получателями / установщиками (поля являются частными дляпо умолчанию методы общедоступны).c и d также являются частными переменными.Но дополнительный private[this] делает d доступным непосредственно внутри класса, а не частным получателем / установщиком.

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

ОБНОВЛЕНИЕ: В комментариях вы спрашиваете о переименовании геттеров / сеттеров.Вот еще более сложный пример.Геттеры / сеттеры вычисляют значение на основе двух полей одновременно:

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...