2012-02-02 3 views
1

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

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

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

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

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

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

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

Edit:

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

ответ

4

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

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

Тем не менее, Single Responsibility Principle также применяется на уровне пакета, поэтому я бы рекомендовал небольшие, сфокусированные библиотеки вместо огромных универсальных библиотек. Это также облегчает выбор лучших в своем классе библиотек.

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

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

1

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

+0

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

+0

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

+0

Я не согласен, ваше «решение» без проблем может усложнить ситуацию, потому что нечего решать. Зависимости должны быть разрешены инструментом или чем-то «внешним», а не кодом! Это не развязка, это похоже на антипаттерн для меня. Мое мнение, конечно. – vulkanino

1

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


Update 1:

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

E.g. Библиотека Mok-mocking зависит от CastleDynamicProxy. Зачем вам это нужно? Вы получаете сборку, в которой DynamicProxy уже объединен, и вы можете просто использовать Moq. Вы никогда не видите, не используете или не должны заботиться о DynamicProxy. Поэтому, если DP API изменится, это не повлияет на ваши тесты, написанные с использованием Moq. Moq изолирует ваш код от изменений в API базового DP.

Update 2:

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

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

+0

Вы имеете в виду что-то вроде 'API1', предоставляя свои собственные интерфейсы для функциональности' API2' в тех местах, где 'API2' используется в' API1'? –

+0

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

 Смежные вопросы

  • Нет связанных вопросов^_^