Работа с системой СИ на Java

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

Система СИ и взаимосвязи между единицами физических величин.
Система СИ и взаимосвязи между единицами физических величин.

Библиотека по работе с единица системы СИ KotUniL, разработанная изначально на Kotlin, недавно сделана мультиплатформенной. В частности, она доступна теперь и на JavaScript, о чём написано здесь.

А зачем нужна эта библиотека?

Программируя традиционным образом, очень просто упустить из виду, в каких единицах измеряются числа, с которыми мы оперируем. Например, можно сложить метры с литрами, и никакой компилятор нам при этом не поможет. 

Эта проблема реальная и уже доказано приводила к авариям, обошедшимся во многие миллионы долларов. (Одна из историй здесь).

Избежать этого помогает использование специальных библиотек, которые корректно работают с физическими единицами системы СИ типа метров или ваттов и иными единицами типа валют или штук. 

Одна из таких библиотек - KotUniL (si-units).

Использование технологии Kotlin Multiplatform позволяет из кода на Kotlin получить код для целого ряда платформ, в том числе для JVM.
А это означает, что тем самым реализованную в библиотеке функциональность можно использовать из Java-программ. (Строго говоря, этого можно было достичь и не используя Kotlin Multiplatform, но в данном случае мы получаем JVM-библиотеки автоматически вместе с другими вариантами, что экономит наши усилия).

Как её использовать?

А как использовать библиотеку из Java?
Подключить библиотеку в ваш проект можно как dependency:

repositories {
    mavenCentral()
}

dependencies {
    implementation("eu.sirotin.kotunil:kotunil-jvm:<version>")
}

На момент написания статьи последняя версия была 4.1.1

Какие различия между вариантами на Kotlin и Java существуют?

А дальше всё тоже самое, как в Kotlin? К сожалению, есть два важных отличия.

Во первых, Java не поддерживает operator overloading и поэтому код смотрится менее элегантно, чем на Котлин.

Рассмотри, например, такую задачку: Маша протирала снаружи стекло аквариума, задела стоявшую рядом вазу, в результате чего стекло аквариума разбилось и вода вытекла на пол. В аквариуме до этой неприятности было 32 литра воды. Комната Маши имеет длину 4 метра и ширину 4,3 метра. На какой высоте в мм. находится сейчас вода в комнате, при условии, что она осталась там и не вытекла?

На Котлине решение выглядит таким образом:

val s = 4.m * 4.3.m
val h = 32.l/s 

А на Java нам приходится вместо знаков арифметических операций над размерными единицами использовать функции:

Expression s = m.times(4).times(m.times(4.3));
Expression v = L.times(32);
Expression h = v.div(s)

Однако все остальные прелести KotUniL сохранены. Амперы с секундами складывать нельзя, а перемножать и делить можно.

Во-вторых, трансформируя код Kotlin в код на Java, транспилер создаёт для классов библиотеки из одного Kotlin-класса два Java-класса. Поэтому, например, работая с метрами мы должны в Java-импорты добавлять строку:

import static eu.sirotin.kotunil.base.MetreKt.*;

Дальнейшую информацию о KotUniL вы надаете в репозитории на GitHub ( см. подробный пример работы с единицами системы СИ в Java в модуле app/jvm/java-console).

Про теоретические основы и особенности использования KotUniL вы можете прочитать и в этой серии стаей: 

  1. Магия размерностей и магия Котлина. Часть первая: Введение в KotUniL  

  2. Магия размерностей и магия Котлина. Часть вторая: Продвинутые возможности  KotUniL

  3. Магия размерностей и магия Котлина. Часть третья: Смешение магий

А есть ли альтернативы?

Я разработал KotUniL, поскольку ни одна из существовавших на тот момент библиотек меня не удовлетворяла. В Java сообществе существует JSR 385. Очевидным образом у разработчиков этой спецификации были схожие с моими мотивации. Но там разработчики пошли по пути выделения размерностей. У них получились Quantity<Volume>Unit<Length> и так далее. Разумеется, всех возможных комбинаций таким образом не покрыть, но множеству приложений этого делать и не придётся.

Вот статья на Baeldung про общий вид работы с библиотекой.

Дизайн библиотеки мне не понравился. Чего только стоит подобный пример конвертирования метров в километры, взятый мной из рекомендованной выше статьи!:

double distanceInMeters = 50.0;
UnitConverter metreToKilometre = METRE.getConverterTo(MetricPrefix.KILO(METRE));
double distanceInKilometers = metreToKilometre.convert(distanceInMeters );

Используя KotUniL вы это запишите так:

val d = 50.m
val x = d.km

Я понимаю, преимущество JSR 385 состоит в обнаружении ошибок типизации на этапе компиляции, а не в наглядности краткости кода. В этой статье я показываю, что любые формулы KotUniL проверяются на ошибки типизации ровно одним юнит-тестом при наглядности кода, схожей с наглядностью технических и научных статей.

Почему стандарт СИ не реализован в Kotlin?

Итак, в мире Java существует по крайней мере спецификация JSR 385, касающаяся реализации обработки единиц системы СИ, а как обстоят с эти дела в Kotlin?

К сожалению, в числе существующих и разрабатываемых стандартных библиотек Kotlin такой библиотеки пока нет.
Я предложил разработчикам языка включить эту функциональность (не обязательно KotUniL) в состав библиотек, поставляемых вместе с языком: (KT-55556). Но пока не убедил их. Но возможно, если вы, уважаемые читатели, активно проплюсуете это предложение ( а заодно и KotUniL на GitHub :-), то ситуация исправится.

Источник: https://habr.com/ru/articles/748248/


Интересные статьи

Интересные статьи

В данном посте мы расскажем как запустили пилот национальной BugBounty платформы в Казахстане, как из этого родился полноценный международный стартап и почему мы считаем это одной из самых успешных ин...
Продолжаю делиться своим опытом погружения в мир генарта и nft, на этот раз при помощи генеративных грибов. Для тех кто не совсем в теме хотя бы одного из этих слов, предлагаю сначала посмотреть мою п...
Что такое single sign-on? Технология единого входа (Single sign-on SSO) — метод аутентификации, который позволяет пользователям безопасно аутентифицироваться сразу в нескольких приложени...
Эта статья является конспектом материала Effective Aggregate Design Part II: Making Aggregates Work Together.Первая часть была посвящена проектированию небольших агрегатов и их внутр...
Есть такой сегмент продаж B2B. Вроде всё просто: компания продаёт компании. Но если разбираться, то компании-клиенту продаёт менеджер. А компания-продавец должна, как мин...