Подходы развязки API библиотеки? - PullRequest
1 голос
/ 02 февраля 2012

Представьте себе набор библиотек, представляющих некоторые API.Используя инверсию механизмов управления, конкретные реализации будут внедрены в потребляющий проект.

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

Теперь я имею в виду два возможных решения для этого:

  • Создание проекта монолитного API, который объединяет связанный APIбиблиотеки.

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

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

Есть ли лучшее решение дляситуация.Когда лучше объединить несколько API-библиотек в одну большую, а когда нет?Я знаю, что это очень общий вопрос, который я задаю, но давайте на мгновение проигнорируем сроки выполнения, оценки, требования клиентов и технологии, я хочу иметь возможность определить правильный подход, основанный как на достижении максимальной масштабируемости, так и минимального времени обслуживания.Итак, что может быть хорошей причиной для выбора того или иного подхода, или другого, который вы мне могли бы предложить?

Редактировать:

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

Ответы [ 3 ]

4 голосов
/ 03 февраля 2012

Выбор между несколькими огромными библиотеками и множеством маленьких библиотек.

  • Если у вас огромная библиотека, код будет иметь тенденцию быть тесно связанным просто потому, чтонет силы, обеспечивающей давление для проектирования различных элементов в слабосвязанной форме.Риск состоит в том, что становится все труднее и труднее развивать эту библиотеку, потому что существует так много взаимозависимостей, которые необходимо координировать.В качестве примера рассмотрим библиотеку базовых классов .NET.
  • Если у вас множество маленьких библиотек, вы можете рискнуть dll hell .Да, нам обещали много лет назад, что это закончилось, но это не так.Просто попробуйте использовать множество детализированных библиотек с открытым исходным кодом в базе кода приложения, и вы поймете, что я имею в виду.

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

Небольшие библиотеки всегда можно составить / скомпилировать в более крупные библиотеки (в .NET с помощью компоновщика сборки / слияния / переупаковки)утилита), хотя разделить большую библиотеку гораздо сложнее.

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

1 голос
/ 02 февраля 2012

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


Обновление 1:

Если ваше приложение использует Library1 сAPI1, это не должно иметь дело с тем фактом, что Library1 использует Lib2, Lib3, .., LibX.

Например, библиотека Moq Mocking зависит от CastleDynamicProxy.Почему вы должны заботиться об этом?Вы получаете сборку, где DynamicProxy уже объединен, и вы можете просто использовать Moq.Вы никогда не видите, не используете и не заботитесь о DynamicProxy.Так что если DP API изменится, это не повлияет на ваши тесты, написанные с использованием Moq.Moq изолирует ваш код от изменений в API базового DP.

Обновление 2:

Поиск проблемы, действительной для более чем одной ветви, приводит к изменениямвсе они

Если это так, вы создаете не библиотеку, а помощника для очень специфической проблемы, которую НИКОГДА не следует навязывать другим проектам.Общие библиотеки имеют тенденцию вырождаться в коллекцию «может быть полезным где-то в далеком будущем».Не надо!Это всегда будет кусать вас в а **!Если у вас есть решение проблемы, которая возникает в более чем одном месте (например, Guard классы): поделитесь им.Если вы считаете, что можете найти какое-то применение для решения проблемы: оставьте это в проекте, пока у вас действительно не возникнет такая ситуация.Тогда поделись этим.Никогда не делай этого "на всякий случай".

1 голос
/ 02 февраля 2012

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

...