Upgrade to Pro — share decks privately, control downloads, hide ads and more …

API на переправе не меняют - как построить стаб...

API на переправе не меняют - как построить стабильный API

Вам знакомо то чувство, когда обновление того или иного фреймворка на давнем и стабильном проекте взрывает код и превращает его в красно-перечеркнутое месиво? Будучи разработчиками платформы CUBA нам до боли это знакомо. Так за время существования платформы, она поменяла под собой 3 ORM-а, 3 мажорных версии Vaadin, не говоря уже о Spring Framework. При этом, одной из задач, решаемых платформой, является именно сохранение стабильного API, чтобы наши пользователи не страдали от выше обозначенной проблемы и мигрировали на последние версии всех используемых в платформе библиотек. В этом выступлении мы поделимся своим опытом построения API, а также приемами, которые позволяют нам решать проблемы с переездом решений на базе CUBA на up-to-date стек.

Yuriy Artamonov

September 13, 2018
Tweet

More Decks by Yuriy Artamonov

Other Decks in Programming

Transcript

  1. Почему совместимость это важно? Что такое совместимость в реальных проектах?

    Какие типы совместимости бывают? Как защитить себя от несовместимых изменений в Java? С какими реальными проблемами мы сталкиваемся? Как выявить проблемы совместимости в вашем коде? СОДЕРЖАНИЕ 2
  2. Что представляет из себя Java? 1 Java SE - универсальная

    платформа: безопасная, переносимая, высокопроизводительная и богатая функциональностью среда исполнения 2 Java SE базируется на спецификациях: • Java Language Specification • Java Virtual Machine Specification • Java Platform API Specification 3 Спецификации бывают как на реализацию API, так и для пользователей API. 4 Java эволюционирует посредством внесения изменений в спецификации и последующей реализации этих изменений. 4
  3. Что с совместимостью? 1 Разработчики стремятся оптимизировать среду исполнения под

    целевые платформы. 2 Сильные спецификации позволили появиться бесчисленному множеству: • виртуальных машин • реализаций стандартной библиотеки 3 Для обеспечения совместимости создаются Technology Compatibility Kit (TCK). 4 Разработчики виртуальных машин используют дополнительные тесты корректности, производительности, устойчивости. 5
  4. The Java. Language Specification. Third Edition Except for timing dependencies

    or other non-determinisms and given sufficient time and sufficient memory space, a program written in the Java programming language should compute the same result on all machines and in all implementations. 6
  5. Что означает совместимость? Совместимость - это качество программного обеспечения, заключающееся

    в том, что: 1. Ваш код продолжает работать по мере того, как используемое ПО эволюционирует 2. Вы можете получать последние исправления и функциональность без необходимости переписывать код 3. Вы можете вовремя! перейти на новый API, приходящий на замену старому 8
  6. Что означает совместимость в реальном мире? Вы можете использовать новые

    версии ПО с минимально возможными издержками на миграцию. Зависимости от API программных продуктов: • форматы данных • документация • опции и формат вывода консольных утилит • баги! • и даже - скорость работы функций! 9
  7. Типы совместимости На уровне исходного кода При компиляции с новой

    версией библиотеки ваш код продолжает работать как требуется. Бинарная совместимость При замене библиотеки ваше приложение успешно линкуется с новой версией без перекомпиляции. 3 1 2 При использовании старой и новой версии функции вы получаете в результате тот же эффект. Функциональная 10
  8. Java SE 7 1. Изменили спецификацию 2. Текущее поведение посчитали

    верным 3. Даже простое изменение документации может ломать совместимость! 12
  9. А как обеспечить совместимость с багами? java.nio.DatagramChannel #send, #receive, #connect

    Можно включить старое поведение свойством: sun.nio.ch.bugLevel со значениями : 1.4 / 1.5 / 1.6 Баг окончательно исправлен в Java 10: https://bugs.openjdk.java.net/browse/JDK-8184742 14
  10. API может допускать неверное использование Пример: смена алгоритма сортировки в

    списках в JDK 7 Comparison method violates its general contract! Миграция - feature toggle для старого поведения 15
  11. Бинарная совместимость сохраняется • Добавление нового кода: пакета, типа, поля,

    метода • Добавление новых полей в аннотации со значением по умолчанию • Добавление или удаление кода, выбрасывающего unchecked exception • Добавление, удаление или изменение инициализаторов • Удаление модификатора класса abstract • Изменение тела метода или конструктора • Увеличение модификатора доступа (private -> public) • … 16
  12. Бинарная совместимость НЕ сохраняется • Удаление кода: пакета, метода, поля

    • Изменение имени метода • Изменение возвращаемого типа метода • Смена порядка параметров класса (Generics) • Добавление public или protected метода в интерфейс • Добавление модификатора abstract • Добавление в сигнатуру checked exceptions • … К счастью, у нас есть default методы в интерфейсах DEMO 17
  13. Josh Bloch - How to Design a Good API and

    Why it Matters 1. Public APIs are forever - one chance to get it right 2. Minimize accessibility of everything 3. Design and document for inheritance or else prohibit it 18
  14. Бинарная совместимость сериализации 19 Guava - Important Warnings: Serialized forms

    of ALL objects are subject to change unless noted otherwise. Do not persist these and assume they can be read by a future version of the library. Caused by: java.io.EOFException: null at java.io.DataInputStream.readInt(DataInputStream.java:392) ~[na:1.8.0_172] at java.io.ObjectInputStream$BlockDataInputStream.readInt(ObjectInputStream.java:3180) ~[na:1.8.0_172] at java.io.ObjectInputStream.readInt(ObjectInputStream.java:1032) ~[na:1.8.0_172] at com.google.common.collect.Serialization.readCount(Serialization.java:50) ~[guava-18.0.jar:na] at com.google.common.collect.ArrayListMultimap.readObject(ArrayListMultimap.java:160)
  15. Страшное слово Deprecated API объявляется Deprecated если: • небезопасно •

    неэффективно • содержит ошибки • будет скоро удалено • поощряет плохие практики Документируем путь миграции в JavaDoc! Опять весь код ЖЁЛТЫЙ 21
  16. Semantic Versioning https://semver.org/ Автор: Том Престон-Вернер Учитывая номер версии МАЖОРНАЯ.

    МИНОРНАЯ.ПАТЧ, следует увеличивать: • МАЖОРНУЮ версию, когда сделаны обратно несовместимые изменения API. • МИНОРНУЮ версию, когда вы добавляете новую функциональность, не нарушая обратной совместимости. • ПАТЧ-версию, когда вы делаете обратно совместимые исправления. 22
  17. Веб-сервисы и REST-API 1. Версионирование обязательно 2. Можно выполнять простые

    трансформации для обеспечения совместимости 3. Отдельная модель сущностей и DTO для веб-сервиса? 24
  18. Миграция на новый API Виды: • Сборка • Конфигурация •

    Код • Схема данных • Данные • Конфигурация как код 25
  19. CUBA Platform • Open Inheritance • Точки расширения повсюду! •

    Миграции базы данных • Миграции кода • Трансформации REST-API 26
  20. История миграций фреймворка • Vaadin Framework 6 / 7 /

    8 • OpenJPA - Eclipse Link • Java 6 / 7 / 8 / 11 • Gradle 1.0M6 / 4.10 27
  21. Методики для проектирования стабильного API • Экстремальный dog-fooding • Принципы

    SOLID • Внедрение зависимостей (DI) • Все виды автоматического тестирования • Политика версионирования релизов • Политика удаления и замены устаревшего API 28
  22. Инструменты 1 Japicmp - сравнение JAR файлов по API. https://github.com/siom79/japicmp

    (+ JDiff) 2 JAPICC - Java API Compliance Checker. https://lvc.github.io/japi-compliance-checker/ 3 API Management: Amazon / Azure 4 Animal Sniffer - обеспечивает контроль за API при сборке для более старого релиза Java https://mojohaus.org/animal-sniffer 29 Пример: Guava
  23. Заключение • Как автор API вы должны думать о последствиях

    изменений • Как потребитель API вы должны минимизировать риски миграции при помощи соответствующих инструментов • Предупреждения компилятора и JavaDoc - ваши друзья • Не забывайте писать интеграционные тесты 30