«Модульные» принципы Scala - PullRequest
14 голосов
/ 26 июля 2011

Недавно я запутался в том, как организовать свой код Scala, потому что вариантов много.

Существуют ли какие-либо рекомендации для Scala о том, как / когда использовать пакеты, объекты, объекты пакетов для организации кода?

Ответы [ 4 ]

9 голосов
/ 27 июля 2011

Понимание возможностей Scala

Во-первых, нам необходимо понять возможности и ограничения каждой стратегии модульности.

Пакеты

Они работают так же, как в Java. Вы можете использовать много файлов для объявления различных частей одного пакета, и вы можете вкладывать много уровней. Это обеспечивает максимальную гибкость с вашим макетом. Тем не менее, поскольку загрузчики классов по умолчанию ожидают найти только классы и интерфейсы в пакетах, это все, что Scala позволяет вам там разместить. (Классы, черты и объекты.)

Предметы

Объекты могут содержать что угодно - методы, поля, другие объекты, классы, признаки и т. Д. Подклассы, признаки и объекты на самом деле являются их собственными отдельными сущностями, в которых содержащий объект является префиксом с именами (если JVM обеспокоен). Объект должен содержаться целиком в одном файле, и хотя вы можете вкладывать подклассы сколь угодно глубоко, это делается путем искажения все более длинных имен, а не добавления в путь для загрузчика классов.

Объекты упаковки

Проблема с наличием только объектов и пакетов заключается в том, что вам может понадобиться вложенная структура:

scala.xml
scala.xml.include
scala.xml.include.sax

так что вам нужно использовать пакеты (чтобы не было одного гигантского файла и беспорядочно длинных имен классов). Но вы также можете захотеть

import scala.xml._

чтобы сделать доступными различные константы и неявные преобразования, чтобы вам приходилось использовать объект. Пакетные объекты приходят на помощь; по сути, они такие же, как обычные объекты, но когда вы говорите

import scala.xml._

вы получаете как все в пакете (scala.xml._), так и все в соответствующем объекте пакета (scala.xml.package).

Как модулировать ваш код

Теперь, когда мы знаем, как работает каждая часть, существуют довольно очевидные правила организации:

  • Поместите связанный код в пакет
  • Если есть много связанных частей, поместите их в подпакеты
  • Если пакет требует имплицитов или констант, поместите их в объект пакета для этого пакета
  • Если у вас есть терминальная ветвь вашей иерархии пакетов, вы можете выбрать, должен ли это быть объект или объект пакета. Есть несколько вещей, которые объектам пакета запрещается делать (хотя список все меньше и меньше - я не уверен, что что-то осталось, кроме запрета на скрытие других имен в пакете), поэтому обычный объект может быть лучшим выбором. Пока вы не беспокоитесь о бинарной совместимости, потом легко передумаете - просто измените object на package object в большинстве случаев.
2 голосов
/ 27 июля 2011

Помимо пакетов и объектов есть «импликации», которые помогут вам структурировать ваш код. Хорошее руководство по использованию (избегайте неправильного использования) можно найти здесь: http://suereth.blogspot.com/2011/02/slides-for-todays-nescala-talk.html

Я бы также предложил классы типов для структурирования вашего кода. Здесь приятно написать на эту тему: http://debasishg.blogspot.com/2010/07/refactoring-into-scala-type-classes.html

1 голос
/ 26 июля 2011

Я использую пакеты всякий раз, когда могу, то есть когда «модуль» состоит только из определений класса / признаков / объекта.Преимущество пакетов в том, что они доступны напрямую из Java без странного синтаксиса.

Во всех других случаях я использую в основном простые объекты.

Иногда у меня есть один объект пакета на проект в корнепакет проекта.Этот объект пакета хранит все необходимые импликации и наиболее важные классы и объекты.Это позволяет хороший импорт в одну строку для всего проекта.

0 голосов
/ 24 июня 2014

Если вас интересует только пространство имен и разбиение кода на отдельные файлы (как это звучит как OP), см. Ответ @ Rex.

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

По сути, интерфейсы модулей (также известные как подписи в SML) становятся чертами в Scala. Модули (или структуры) являются объектами в Scala. Функторы могут быть преобразованы в классы, абстрактные классы или даже признаки с некоторой реализацией с аргументами функторов, преобразованными в абстрактные поля или аргументы конструктора, в зависимости от того, хотите ли вы, чтобы у получающихся модулей были совместимые типы или нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...