Scala организация проекта

Как организовать код в проекте Scala?

После нескольких лет разработки с Java (в большинстве случаев с использованием Spring) мы пытаемся создать быстрый прототип в Scala.

Один из первых возникших вопросов: мы будем просто использовать одни и те же имена пакетов и организацию кода и просто писать код в Scala?

Например, мы используем помощники для наших сущностей (AccountHelper, CacheHelper...), а также иногда используем службы (AccountService...).

ot: Далее мы также рассмотрим, как перенести наши подмодули maven на sbt, но это совсем другая история.

Ответ 1

Ответ отчасти зависит от того, что для вас наиболее важно. Если вы действительно серьезно относитесь к быстрой части прототипа, то, что касается физического макета файла/каталога, я бы просто начал с одного плоского файла и начинал разбивать его только тогда, когда достаточно кода, чтобы сделать это неловким. Это должно, по крайней мере, облегчить глобальную реструктуризацию вашего кода, пока вы не получите правильную общую структуру. Scala не применяет соответствие пакета: каталог, класс: файл, и учитывая лаконичность Scala, которая во многих случаях может быть излишней. Нет ничего, что могло бы помешать вам организовать вещи в несколько пакетов в одном файле, прежде чем разбить его физически, как только вы получите правильную структуру. На самом деле разбить файл, когда вам нужно, должно быть очень легко.

Вы не очень много говорили о том, что делают ваши классы Helper & Service, но по соглашению об именах они звучат как хорошие кандидаты в общие (или параметрические) черты или классы. Это позволит вам выяснить, что общего у всех помощников (и аналогично для сервисов). У них должно быть много общего, чтобы оправдать соглашение об именах. Затем вы должны будете использовать или, возможно, расширить типы, такие как Helper[Cache] и Service[Account]. Я также предполагаю, что эти типы будут иметь несколько экземпляров с довольно широкой областью действия и могут извлечь выгоду из неявной передачи, превращая Helper[_] и Service[_] в классы типов. Также возможно, что вам больше не понадобится Spring на этом этапе, поскольку неявный поиск может дать вам внедрение зависимости, которое вам нужно. Тем не менее, я просто использую несколько названий классов, которые вы предоставили, и очень много читаю в них, так что есть вероятность, что я здесь совершенно не в себе.

Другая возможность состоит в том, что вспомогательные классы, такие как Helper & Service, являются просто скрытыми замыканиями. Это довольно распространенный случай с такими классами в Java. В этом случае вы должны просто реализовать их как функции в Scala, но опять же, я просто угадываю по именам...

Вы также можете изучить шаблон Layer Cake и посмотреть, имеет ли это смысл для вашего проекта.

Больше информации о вашем проекте, вероятно, даст вам лучший совет, чем эти продукты моего чрезмерного воображения :).

Вот несколько потенциально полезных ссылок:

Ответ 2

Я организовываю пакеты в основном таким же образом, но завершаю реализуя вещи по-разному. Когда я впервые начал писать scala, исходящий из java, мне потребовалось некоторое время чтобы привыкнуть к нескольким вещам:

  • Используйте объекты-компаньоны вместо "статические"

    класс Bla {}  объект Bla {...}

  • Забудьте о "get *", "set *" getters и seters - используйте val, var - prefer val.

  • Познакомьтесь с scala.collection., Option и scala.collection.JavaConversions. - (который обеспечивает неявное преобразование типов java и scala), поэтому вы можете написать такой код:

      class Helper {
          def lookupUser( name:String ):Option[UserInfo]
          ...
       }
    
     val jsonUsers:Seq[String] = 
       Seq( "fred", "mary", "jose" ).flatMap( 
         name => helper.lookupUser( name )
       ).map( info => helper.toJson( info ) )
    

    или

    val jsonUsers:Seq[String] = for ( name <- Seq( "fred", "mary", "jose" );
                                   info <- helper.lookupUser( name )
       ) yield helper.toJson( info )
    

    или

     val jsResult = helper.lookupUser( "fred" ).map( info => helper.toJson( info ) 
                   ).getOrElse( jsErrorRespose )
    

Если вы чувствуете себя комфортно с таким кодом, тогда у вас есть хороший старт...

Удачи!

Ответ 3

У нас уже была вся наша платформа, написанная в java. И я с большим энтузиазмом относился к scala на работе. Поэтому я просто добавил свой код scala к существующей базе кода на том же уровне, то есть src/main/java, и я нашел почти 100% -ную совместимость с scala с java с большой легкостью. Просто включите плагин maven scala, и он работает. Но я бы предложил сохранить код scala под src/main/scala для более чистой организации базы кода, а также помочь в разрешении зависимостей младшего компилятора. Также наличие двойной сборки как в sbt, так и в mvn дает большую гибкость для процесса сборки.