Подтвердить что ты не робот

Должны ли вы обернуть сторонние библиотеки, которые вы примете в свой проект?

Обсуждения, которые я провел сегодня с коллегой.

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

Я не согласен со словом всегда, дискуссия возникла в отношении log4j, и я утверждал, что log4j имеет хорошо протестированный и проверенный временем API и реализацию, и все мыслимое может быть настроено posteriori, и нет ничего вам следует обернуть. Даже если вы хотите обернуть, есть проверенные обертки, такие как commons-logging и log5j.

Еще один пример, который мы затронули в нашем обсуждении, - Hibernate. Я утверждал, что у него очень большой API-интерфейс для упаковки. Кроме того, он имеет многоуровневый API, который позволяет вам настраивать его внутри, если вам это нужно. Мой друг утверждал, что он по-прежнему полагает, что он должен быть завернут, но он не сделал этого из-за размера API (этот сотрудник намного ветеран, чем я, в нашем текущем проекте).

Я заявлял этот и что обертка должна выполняться в определенных случаях:

  • Вы не знаете, как библиотека будет соответствовать вашим потребностям.
  • вы будете использовать только небольшую часть библиотеки (в этом случае вы можете выставить только часть своего API).
  • вы не уверены в качестве API-интерфейса библиотеки или реализации.

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

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

4b9b3361

Ответ 1

Это прекрасный пример для YAGNI:

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

Ответ 2

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

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

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

Это определенно не "всегда" ситуация. Это то, что может быть желательно. Но время не всегда будет там, и, в конце концов, если писать обертку занимает несколько часов, а изменения в долгосрочной версии библиотеки кода будут немногочисленны и тривиальны... Зачем беспокоиться?

Ответ 3

Проблема здесь частично в том, что слово "обертка", частично ложная дихотомия, и частично ложное различие между JDK и всем остальным.

Слово "обертка"

Обертка всего Hibernate, как вы говорите, является полностью непрактичным предприятием.

Ограничение зависимостей Hibernate с идентифицированным, контролируемым набором исходных файлов, с другой стороны, вполне может быть практичным и достичь тех же результатов.

Ложная дихотомия

Ложная дихотомия - это отказ признать третий вариант: стандарты. Если вы используете, скажем, аннотации JPA, вы можете заменить Hibernate на другие вещи. Если вы пишете веб-службу и используете аннотации JAX-WS и JAX-B, вы можете менять их между JDK, CXF, Glassfish или любым другим.

Фальшивое различие

Конечно, JDK медленно меняется и вряд ли умрет. Но крупные пакеты с открытым исходным кодом также медленно меняются и вряд ли умрут. Неопубликованные тысячи разработчиков и проектов используют Hibernate. На самом деле больше нет риска смены Hibernate или внесения радикальных несовместимых изменений API, чем сама Java.

Ответ 4

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

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

Я бы пошел только с обертками, если бы знал наверняка, что мне придется поддерживать несколько разных и существенно разных библиотек в производстве.

Ответ 5

Я согласен со всем, что было сказано в значительной степени.

Единственный временный пакет стороннего кода полезен (бар, нарушающий YAGNI) для модульного тестирования.

Издевательская статика и т.д. требует, чтобы вы обернули код, это действительная причина для написания обертков для стороннего кода.

В случае кода ведения журнала его не нужно, однако.

Ответ 6

Основным фактором принятия решения об обертке библиотеки или нет является влияние изменения библиотеки на код. Когда библиотека вызывается только из 1 класса, влияние меняющейся библиотеки будет минимальным. Если на другой стороне библиотека вызывается во всех классах, оболочка гораздо более вероятна.

Ответ 7

  • Любая неопределенность в выборе сторонней библиотеки должна быть очищена в начале проекта с использованием прототипов для проверки масштабируемости/пригодности/вне зависимости от сторонней библиотеки.

  • Если вы решите пойти вперед и обеспечить полную поддержку де-связи/абстракции, это должно быть оценено и в конечном итоге одобрено спонсором проекта - в конечном счете это коммерческое решение, поскольку кто-то должен заплатить за это и требуемую работу сделать это (если это не будет абсолютно тривиально, и в этом случае api, вероятно, будет иметь низкий риск).

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

Ответ 8

Нет. Java-архитекторы/wanna-bees слишком заняты проектированием против мнимых изменений.

С современной IDE это кусок пирога, когда вам нужно изменить. До тех пор держите его простым.

Ответ 9

Я бы согласился с большинством ваших вопросов. Использование абсолютов часто приводит вас к неприятностям и говорит, что вы должны "всегда" делать что-то, ограничивающее вашу гибкость. Я бы добавил еще несколько баллов в ваш список.

Когда вы используете код обхода вокруг очень распространенного API, например Hibernate или log4j, вы затрудняете привлечение новых разработчиков. Новые разработчики теперь должны изучить совершенно новый API, где, если бы вы не завернули код, он был бы очень хорошо знаком.

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

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

Я определенно не говорю, что код упаковки всегда плох, но, как вы сказали, есть много факторов, которые вы должны учитывать.

Ответ 10

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

Если вы абсолютно уверены, что никогда не будете (другое абсолютное) использовать в своем проекте другую структуру ведения журнала, продолжайте и пропустите оболочку. Даже, сказав это, я бы, вероятно, задержался, написав обертку, пока не узнал, что мне это нужно, как в первый раз, когда мне нужно переключиться.

Ответ 11

Это довольно забавный вопрос.

Я работал в системах, в которых мы обнаружили ошибки в библиотеках, которые мы использовали, и какой вверх по течению либо больше не поддерживал, либо не интересовался фиксацией. На языке, подобном Java, вы обычно не можете исправить внутренние ошибки из оболочки. (К счастью, если они с открытым исходным кодом, вы можете по крайней мере исправить их самостоятельно.) Так что здесь не поможет.

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

Кроме того, ваш коллега рисует линию в вещах, называемых "библиотеками"? Что относительно самой Java? Он обертывает встроенные классы? Он обертывает файловую систему? Планировщик потоков? Ядро? (То есть, с его собственными обертками - в некотором смысле, все это оболочка вокруг процессора, но похоже, что он говорит об обертках в вашем исходном репо, которые полностью находятся под вашим контролем.) У меня были встроенные функции изменять или исчезать при появлении новых версий. Java не застрахован от этого.

Итак, идея всегда писать обертку сводится к ставке. Предполагая, что он только обертывает сторонние библиотеки, он, как представляется, неявно делает ставку на то, что:

  • "Первоначальная" функциональность (например, сама Java, ядро ​​и т.д.) никогда не изменится.
  • когда функциональность "сторонней" изменяется, она всегда будет выполняться таким образом, который может быть исправлен в обертке

Это правда в вашем случае? Я не знаю. Из средних проектов Java, которые я сделал, это редко бывает для меня. Я бы не тратил усилий на то, чтобы обернуть все сторонние библиотеки, потому что это кажется бедной ставкой, но ваша ситуация, безусловно, отличается от моей.

Ответ 12

Есть одна ситуация, когда вы с серьезной причиной можете обернуть. А именно, если вам нужно протестировать материал, а объект третьей стороны по умолчанию - тяжелый. Тогда интерфейс может действительно иметь значение.

Обратите внимание, что это не замена библиотеки, но сделать ее управляемой, где это не имеет большого значения.

Ответ 13

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

  • Если требуется слишком много изменений и дополнений, это скорее всего не библиотека, которую вы ищете.
  • если есть умеренное количество дополнений и модификаций - всегда есть шаблоны дизайна, которые пригодится в этих случаях. Например, шаблон Decorator (например, добавление нового/дополнительного поведения к существующему объекту динамически), например, вполне подходит для большинства случаев.
  • Возможности поиска/замены IDE и возможности рефакторинга предлагают простой способ изменить код во всех необходимых местах, если требуется какое-то важное изменение, и появится объект-оболочка. (конечно, здесь будут полезны юнит-тесты;))

Ответ 14

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

Мой инстинкт - обратиться к принципу YAGNI (вам это не понадобится) и выбрать "редко".

Ответ 15

Я бы не обернул его как одну-единственную вещь, но я бы слоем приложение, чтобы каждая часть была сменена как можно больше. Модель ISO OSI хорошо работает для всех типов программного обеспечения: -)

Ответ 16

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

Обертка обычно не дает вам ничего, если она не отвечает определенной цели (например, полиморфизация неполиморфной конструкции). Они часто появляются в рефакторинге, но я бы не рекомендовал создавать на них архитектуру. Конечно, есть несколько исключений, но есть какой-то принцип.

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