Как структурировать функциональный код в Kotlin? - PullRequest
0 голосов
/ 21 декабря 2018

Мне интересно, каков наилучший способ структурировать функциональный код в Kotlin.

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

Способ объекта:

object Container {
    fun myFunc() = ...
}

...

Container.myFunc()

Способ упаковки:

package myPackage

fun myFunc() = ...

...

myPackage.myFunc()

Способ стрелки:

interface Container {
    companion object {
        fun Container.myfunc() = ...
    }
}

...

Container.myFunc()

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

Person.Repository.getById(id: UUID)

1 Ответ

0 голосов
/ 21 декабря 2018

Если я правильно вас понимаю, вам нужна концепция пространств имен (структурированная иерархическая область для доступа к символам).

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

  1. object объявлений. Они в значительной степени удовлетворяют потребности, однако приводят к созданию реального объекта вJVM и представьте новый тип, который вам не нужен.Команда Jetbrains , как правило, не рекомендует использовать объекты в качестве пространств имен , но это, конечно, еще вариант.Я не вижу, как сопутствующие объекты внутри интерфейсов добавляют какую-либо ценность.Возможно, идея состоит в том, чтобы ограничить область видимости классами, которые реализуют интерфейс.

  2. Функции верхнего уровня. Хотя и возможно, функции верхнего уровня в Kotlin загрязняют глобальные функции.namespace, и call-site не позволяет указать, к чему они принадлежат.Конечно, можно обойтись, но все они довольно уродливы:

    • Полностью квалифицировать пакет com.acme.project.myFunc()
    • Использовать преднамеренно короткий, но больше не представляющий домен пакет functional.myFunc()
    • Вызов функции без пакета, но с префиксом package_myFunc()
  3. Функции расширения. Если функциональность тесно связана собъекты, над которыми он работает, функции расширения - хороший вариант.Вы видите это для стандартных коллекций Kotlin и всех их функциональных алгоритмов, таких как map(), filter(), fold() и т. Д.

  4. Глобальные переменные. Это делаетне добавляет много по сравнению с object подходом, просто мешает вам ввести именованный типИдея заключается в создании любого объекта, реализующего один или несколько интерфейсов (к сожалению, без интерфейсов объявленные функции не доступны глобально):

    interface Functionals {
        fun func(): Int
    }
    
    val globals = object : Functionals {
        override fun func() = 3
    }
    

    Это в основном удобно, если ваш объект реализует различные интерфейсы, так что выможет передавать только часть функциональности различным модулям.Обратите внимание, что то же самое может быть достигнуто только с помощью object с, поскольку они также могут реализовывать интерфейсы.

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