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

Перенос Java на Scala

Каковы наиболее важные моменты, о которых нужно знать, и обходные пути при постепенной миграции существующей кодовой базы Java на Scala? С (потенциально очень длинной) промежуточной фазой, в которой используются оба языка.

Вот о чем я думаю:

  • различные иерархии коллекций
  • Конструкции Java, которые Scala не могут нормально работать
  • Scala, которые нецелесообразно использовать в Java
  • инструменты сборки
  • порядок компиляции
  • поддержка неизменности в рамках
  • и др.
4b9b3361

Ответ 1

Scala не нравится:

  • внутренние классы Java
  • статические методы и переменные (особенно в суперклассах)
  • необработанные типы

Java не нравится:

  • Scala свойства объектов
  • закрытие
  • актеры (кроме Скарлетт Йоханссон и Акка Актеры, так как у них есть Java API)
  • implicits, особенно Manifests
  • конструкции расширенного типа (более высокие типы типов, структурные типы, абстрактные типы vars)

Ответ 2

Изначально (т.е. первая фаза миграции), я бы сказал, что вы не хотите экспортировать API (интерфейс/общедоступный метод и т.д.) с помощью сложной в использовании-Java-конструкции scala.

На практике я бы ограничил это экспортом чего-либо, что является scala -специфичным (опять же, я говорю о первой фазе миграции здесь):

  • scala классы библиотек (типы функций, коллекции и т.д.)
  • сигнатуры общего типа общего типа
  • implicits

Так что же это? Ну, внутренности классов (частные методы, поля и т.д.) Могут быть преобразованы для использования конструкций scala и классов библиотеки.

Если у вас есть какие-либо API-интерфейсы (особенно клиентские API-интерфейсы, которые вы собираетесь перенести), я бы разработал их заново с нуля в Scala; сначала с использованием Java-сервера. Затем я медленно еду в коде между ними.

Из выделенных вами пунктов я бы согласился с тем, что неизменяемая парадигма scala и изменчивая парадигма Java не очень хорошо сочетаются. Другие пункты, которые я нашел менее проблематичными.

Другим основным моментом несоответствия парадигмы является способ преобразования любого параллельного кода, который у вас есть (т.е. использующего java.util.concurrent). Разумеется, это можно преобразовать, но вопрос заключается в том, следует ли заменить модель concurrency на основе блокировки с помощью метода actors или STM. В любом случае это также, вероятно, будет полная реорганизация, в отличие от конверсии как таковой.

Ответ 4

Один трюк, который мне нравится использовать, я определяю объект, используя идиоматические свойства Scala (vals и vars), затем добавьте аннотацию @BeanProperty, чтобы выставить в качестве свойств JavaBean. Таким образом, каждый язык может использовать родные идиомы.

Аннотация @BeanInfo также может использоваться на уровне класса для аналогичной цели, но вы должны быть осторожны здесь. При использовании @BeanInfo любые методы, которые вы дополнительно настраиваете как setXXX или getXXX, не будут подвергается интроспекции bean. Это важно, так как вам нужно вручную писать getters/seters для типов коллекций, если вы также хотите обрабатывать перевод между, например, Scala Списки и списки Java.

Ответ 5

Я добавлю к тому, что говорили другие, поскольку они правильны и значимы. Больше, чем просто код, вам нужно будет выполнить свои модульные тесты. Это не сильно звучит, пока вы не начнете изменять мутируемость и потоковые конструкции, все еще пытаясь заставить все работать так же, как и раньше. Во время перехода очень важно учесть все краевые случаи, открывая дополнительные краевые случаи, которые вы можете ввести во время миграции.

Если вы принесете свои модульные тесты в хорошую платформу тестирования Scala, такую ​​как ScalaTest, с прямым переводом, вы можете обнаружить, что то, что вы тестируете, не то, что вы тестировали раньше. При выполнении вашей миграции важно, чтобы вы сохраняли намерение кода вместе с тестами вместо того, чтобы допускать фрагментацию мысли.