Ждал этого сообщения, ведь у каждого ИИ означает разное. Один копипастит из Дипсика, а другой обложится Opus 4.6 с оркестраторами, скиллами и MCP. Которые сами себя изведут, но выдадут подходящее решение и даже доку напишут для других) И это совершенно разный уровень получаемого результата)
Уже есть поддержка, вот что пришло в первую очередь:
Kotlin имеет inline value classes — это лёгкие обёртки над примитивами с инвариантами, без overhead на runtime. Пример:value class Weight(private val grams: Long) , компилятор “инлайнит” его как long, но даёт типобезопасность и методы.
Rust использует newtype pattern: pub struct Weight(pub u64); — zero-cost абстракция, где компилятор оптимизирует до голого числа, но с отдельным типом для предотвращения ошибок.
Не-а, не кажется 🙂 Я не предлагаю всем срочно делать VO и что без этого у нас всё развалится. Нет, это просто подход, который может решить некоторые проблемы.
где-то должно быть написано, что Left - это ошибка, а Right - это значение
В доке библиотеки написано) By convention the success case is Right and the failure is Left. Это как с assertEquals(a , b) в JUnit, что первое, а что второе. Благо AssertJ упрощает и уже на надо запомнить это соглашение о порядке элементов. И использование внешней библиотеки или подхода должно быть не внезапным событием для ревьювера, а заранее спланированных событием.
Чтобы это не создавало когнитивную нагрузку, то всегда можно сузить возможности для разработчика и отдать это компилятору:
Either<DomainError, T>
В данном случае накосячить с правой стороной сложно, а с левой - "а давайте для случаев, когда нужно возвращать VIP статус, будем там возвращать строчку "VIP", а если не "VIP" - то сообщение об ошибке.
Ок, если рассматривать текст статьи как бездумный копипаст и использовать String, то да. Полностью прав с вашим комментом, но у нас есть же объекты. Вы можете возвращать, то что вам удобно. Можно сделать sealed класс с исключениями DomainError, а там используйте что удобно и готовый текст или код ошибки для дальнейшей локализации ответа. По сути вы это и описали во второй части комментария – делаем систему возвратов строго типизированной. И я разделяю этот подход.
А возможно я тут и сам попал в Primitive Obsession силки 😁 кто знает)
Это совсем не проблема VO, вы можете писать обычные сервисы и дто имея разные API. Так что это вопрос может касаться конкретного языка или договоренностей в команде. VO не делает это лучше или хуже, это делают люди. Ну с перегрузкой нельзя не согласиться.
В Java тоже обычно используют BigDecimal для точности. Но есть бесячая проблемка. Если в C# при сравнении decimal "созданной с разной точностью" сравнения происходят без проблем:
decimal a = 1.1m;
decimal b = 1.10m;
Console.WriteLine(a == b); // true
Console.WriteLine(a.Equals(b)); // true
То в Java разная точность и надо сравнивать через compare, так как через equals не будет true. Поэтому связываться с этим в бизнес логики совсем неинтересно:
var a = new BigDecimal("1.10"); //scale = 2
var b = new BigDecimal("1.1"); //scale = 1
System.out.println(a.equals(b)); //false
System.out.println(a.compareTo(b) == 0); //true
System.out.println(a.setScale(2).equals(b.setScale(2))); //true
Строки взяты для быстрой настройки scale и для точности.
Конечно есть, в Java есть стандарт JSR 385 (Units of Measurement API 2.0) и популярная реализация это библиотека Indriya. Мы его используем, особенно востребована библиотека в "международных" сервисах, когда величины разные и зависят от страны.
В некоторых случаях используется дополнительная обертка над библиотечными классами для добавления собственных свойств и инвариантов. Почему используется не всегда и везде, потому что иногда это избыточно и усложняет код.
Для денег тоже есть устоявшаяся библиотека JSR 354 RI Moneta. И я бы ее рекомендовал для работы с деньгами по умолчанию.
Да, вы правы, окрулять не надо если у нас и так целые значения и храним в long.
Мне хотелось этим показать, что можно упаковать в метод правила округления.
Думаю вариант с аргументов double лучше демонстрирует идею:
public static DiscountRate ofFraction(double raw) {
var bd = BigDecimal.valueOf(raw);
var normalized = bd.setScale(2, RoundingMode.HALF_UP);
return new DiscountRate(normalized);
}
Хотя если копать дальше, я бы предпочёл округлять и нормализовать scale именно в конструкторе в итоге, тогда точно будет одна точка подготовки данных.
По сути, где это будет не так важно, это может быть даже Tilda, DokuWiki и прочее. Для селлера достаточно ссылку иметь по которой всегда будет актуально. Я не очень люблю PDF, так как они устаревают и надо как-то всех уведомить "Скачайте новое" или сделать рассылку, чтобы этот PDF все получили.
Думаю генерить PDF при изменении доки и предлагать этот вариант это хорошее дополнение, кто любит твёрдый формат в виде файла у себя локально)
Кстати отличная идея, пак сделать несложно, накидываешь в конфиг файлик нового расширения другие расширения и получаешь свой vsix файл. Согласен,а то по ссылкам бегать и одинаковые кнопки жать хоть и надо один раз - но муторно. У меня даже есть заготовка, надо дожать и будет проще получить готовую альтернативную среду.
Ждал этого сообщения, ведь у каждого ИИ означает разное. Один копипастит из Дипсика, а другой обложится Opus 4.6 с оркестраторами, скиллами и MCP. Которые сами себя изведут, но выдадут подходящее решение и даже доку напишут для других) И это совершенно разный уровень получаемого результата)
Уже есть поддержка, вот что пришло в первую очередь:
Kotlin имеет inline value classes — это лёгкие обёртки над примитивами с инвариантами, без overhead на runtime. Пример:
value class Weight(private val grams: Long), компилятор “инлайнит” его как long, но даёт типобезопасность и методы.Rust использует newtype pattern: pub struct Weight(pub u64); — zero-cost абстракция, где компилятор оптимизирует до голого числа, но с отдельным типом для предотвращения ошибок.
Также примеры на C# тоже укладываются в «есть прямо сейчас», а Java ждёт проекта Valhalla. На Хабре писали про это Project Valhalla: эпичный квест Java за перфомансом)
красиво и синтаксис понятный)
Вы сделали разные типы? И каждый выводит TPoint? Интересно узнать, что тут значит равнозначные.
Отличие есть, крато:
Newtype это только про типовую безопасность. Обернули String → получили другой тип. Не получили overhead, а компилятор не обманешь.
Думаю с учетом примера на Rust его дока и подходит. Rust Design Patterns – Newtype
ValueObject пошире, это можно сказать "усложненный" newtype, включающий инварианты и может содержать не одно поле при необходимости.
😁 И всё это придумали не джависты, не во всем они виноваты)
Спасибо за поддержку! Я бы сказал, что это очень смело на Хабре высказываться за автора! Жму руку)
Не-а, не кажется 🙂
Я не предлагаю всем срочно делать VO и что без этого у нас всё развалится. Нет, это просто подход, который может решить некоторые проблемы.
P.S. на коммент ответил :)
В доке библиотеки написано) By convention the success case is Right and the failure is Left. Это как с
assertEquals(a , b)в JUnit, что первое, а что второе. Благо AssertJ упрощает и уже на надо запомнить это соглашение о порядке элементов. И использование внешней библиотеки или подхода должно быть не внезапным событием для ревьювера, а заранее спланированных событием.Чтобы это не создавало когнитивную нагрузку, то всегда можно сузить возможности для разработчика и отдать это компилятору:
Ок, если рассматривать текст статьи как бездумный копипаст и использовать String, то да. Полностью прав с вашим комментом, но у нас есть же объекты. Вы можете возвращать, то что вам удобно. Можно сделать sealed класс с исключениями DomainError, а там используйте что удобно и готовый текст или код ошибки для дальнейшей локализации ответа. По сути вы это и описали во второй части комментария – делаем систему возвратов строго типизированной. И я разделяю этот подход.
А возможно я тут и сам попал в Primitive Obsession силки 😁 кто знает)
Это совсем не проблема VO, вы можете писать обычные сервисы и дто имея разные API. Так что это вопрос может касаться конкретного языка или договоренностей в команде. VO не делает это лучше или хуже, это делают люди. Ну с перегрузкой нельзя не согласиться.
Это псевдокод) там нет new если мы говорим о Java синтаксисе. И подразумевает, что объекты созданы на основе одинаковых значений.
Но мне нравится это замечание и я верну синтаксис Java, чтобы не было вопросов и затыков при чтении)
Коммент для треда "ваша джава творит дичь" :)
В Java тоже обычно используют BigDecimal для точности. Но есть бесячая проблемка. Если в C# при сравнении decimal "созданной с разной точностью" сравнения происходят без проблем:
То в Java разная точность и надо сравнивать через compare, так как через equals не будет true. Поэтому связываться с этим в бизнес логики совсем неинтересно:
Строки взяты для быстрой настройки scale и для точности.
Конечно есть, в Java есть стандарт JSR 385 (Units of Measurement API 2.0) и популярная реализация это библиотека Indriya. Мы его используем, особенно востребована библиотека в "международных" сервисах, когда величины разные и зависят от страны.
В некоторых случаях используется дополнительная обертка над библиотечными классами для добавления собственных свойств и инвариантов. Почему используется не всегда и везде, потому что иногда это избыточно и усложняет код.
Для денег тоже есть устоявшаяся библиотека JSR 354 RI Moneta. И я бы ее рекомендовал для работы с деньгами по умолчанию.
Да, вы правы, окрулять не надо если у нас и так целые значения и храним в long.
Мне хотелось этим показать, что можно упаковать в метод правила округления.
Думаю вариант с аргументов double лучше демонстрирует идею:
Хотя если копать дальше, я бы предпочёл округлять и нормализовать scale именно в конструкторе в итоге, тогда точно будет одна точка подготовки данных.
Да, они вечером этого же дня отменили бронь)
Никаких открыток! Никакого праздника! Только деньги вернули) И еще сказали «В конце описания же было написано, что тестовая квартира»
По сути, где это будет не так важно, это может быть даже Tilda, DokuWiki и прочее. Для селлера достаточно ссылку иметь по которой всегда будет актуально. Я не очень люблю PDF, так как они устаревают и надо как-то всех уведомить "Скачайте новое" или сделать рассылку, чтобы этот PDF все получили.
Думаю генерить PDF при изменении доки и предлагать этот вариант это хорошее дополнение, кто любит твёрдый формат в виде файла у себя локально)
Ох, уж эти тестовые лоты) Как-то забронировал квартиру посуточно в другом городе – а она оказалась тестовая 😆
👍 Отличный гайд - все в одном месте! Интересно, как быстро он устареет?
Кстати отличная идея, пак сделать несложно, накидываешь в конфиг файлик нового расширения другие расширения и получаешь свой vsix файл. Согласен,а то по ссылкам бегать и одинаковые кнопки жать хоть и надо один раз - но муторно. У меня даже есть заготовка, надо дожать и будет проще получить готовую альтернативную среду.
Ну тут автоимпортам приходится пока еще поработать, не у всех же разом работу отнимать)