Как сделать код совместимым с другой версией библиотеки, чтобы иметь возможность работать в разных средах? - PullRequest
0 голосов
/ 10 января 2019

Я работаю над SQL-инструментом для извлечения и отображения данных из экосистемы Hadoop. Я использовал библиотеки Spark и Hive для обеспечения возможности подключения и просмотра SQL.

Я использую некоторые API, классы, которые я расширил из Spark и Hive и их внутренних методов, которые я использовал. Теперь многие API, конструкторы классов и синтаксис методов изменились.

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

В моем инструменте мне пришлось расширить многие классы Spark SQL и написать свои собственные реализации. Для поддержки нескольких версий Spark в настоящее время я использую рефлексию для достижения совместимости вызовов методов / API Spark.

Пример: Скажем, ThriftBinaryCLIServive - это класс, который я расширил. Конструктор изменился в Hive1.2 и Hive2.1. В Hive1.2, ThriftBinaryCLIServive (CLIService cliService) В Hive2.1, ThriftBinaryCLIServive (CLIService cliService, Runnable oomHook)

Чтобы решить это Я написал отдельную версию расширенных классов: CustomThriftBinaryCLIServive1_2 (совместимый с Hive 1.2) и CustomThriftBinaryCLIServive2_1 (совместимый с Hive 2.1) и сохраняют их в разных исходных папках. Я использую Maven для компиляции пакетов в определенных исходных папках одновременно. Я использую отражение для создания экземпляра соответствующего класса во время выполнения в зависимости от версии Hive и использую ThriftBinaryCLIServive в качестве ссылочного класса.

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

Я также попробовал подход Custom Class Loader, в котором я использовал два разных загрузчика классов для загрузки классов разных версий, но это не сильно помогло, к тому же это не так легко в долгосрочной перспективе и трудно отладить.

Может кто-нибудь предложить другие лучшие способы, которыми я могу решить эту проблему?

Ответы [ 2 ]

0 голосов
/ 10 января 2019

Программа с наименьшим общим знаменателем. Если версия 1 предоставляет функцию A, а версия 2 предоставляет функции A и B, в своем коде вы можете использовать функцию A, но не функцию B.

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

Используйте современную систему контроля версий, которая позволяет легко разрабатывать ветвления. Согласитесь, что вам придется одновременно работать над разными версиями вашего кода одновременно, объединяя ветки (для разных версий). Слияние старых версий с новыми версиями обычно работает лучше.

Примите, что вы не можете поддерживать старые версии вечно. Как старые версии библиотеки устаревают и больше не поддерживаются, так и старые версии вашего кода должны.

0 голосов
/ 10 января 2019

Для этой цели можно использовать адаптер design pattern. Всякий раз, когда новая версия вводится с другим API, вам нужно будет просто ввести новый Adapter, который будет направлять вызов из существующего кода в новый API.

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