Предложения по добавлению возможностей плагина?

Есть ли общая процедура для программирования возможности расширения в вашем коде?

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

Зависят ли такие вещи от языка, на котором была написана система, или есть общий метод, позволяющий это сделать?

Ответов (6)

Решение

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

Если, например, у вас есть программа, написанная на C, для Windows плагины будут написаны для вашей программы как библиотеки DLL. Во время выполнения вы должны вручную загрузить эти библиотеки DLL и предоставить им некоторый интерфейс. Например, библиотеки DLL могут предоставлять gimme_the_interface() функцию, которая может принимать структуру, заполненную указателями функций. Эти указатели на функции позволят DLL выполнять вызовы, регистрировать обратные вызовы и т. Д.

Если бы вы были на C++, вы бы использовали систему DLL, за исключением того, что вы, вероятно, передали бы указатель на объект вместо структуры, и объект реализовал бы интерфейс, который предоставлял бы функциональные возможности (выполняя то же самое, что и структура, но менее уродливо). Для Java вы должны загружать файлы классов по запросу вместо библиотек DLL, но основная идея останется той же.

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

PS Если вы хотите увидеть хороший пример системы плагинов C++, посмотрите foobar2000 SDK . Я не использовал его довольно давно, но раньше он был очень хорош. Я полагаю, что это все еще так.

Если вы используете скомпилированный язык, такой как C или C++, может быть хорошей идеей взглянуть на поддержку плагинов с помощью языков сценариев. И Python, и Lua - отличные языки, которые используются для написания сценариев большого количества приложений (Civ4 и блендер используют Python, Supreme Commander использует Lua и т. Д.).

Если вы используете C++, ознакомьтесь с библиотекой boost python. В противном случае python поставляется с заголовками, которые можно использовать в C, и неплохо справляется с документированием C / python API. Документация для Lua казалась менее полной, но, возможно, я недостаточно внимательно ее искал. В любом случае вы можете предложить довольно надежную платформу для написания сценариев без огромного объема работы. Это все еще нетривиально, но дает вам очень хорошую основу для работы.

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

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

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

Некоторые люди также создают язык сценариев для своей системы или реализуют интерпретатор для подмножества существующего языка. Это тоже возможный путь.

Итог: когда вы загружаете код, только ваше воображение сможет вас остановить.
Удачи.

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

Например, если вы пишете приложение для ведения блога, вы можете захотеть инициировать событие непосредственно перед сохранением нового сообщения в базе данных и предоставить HTML-код сообщения в плагин для изменения по мере необходимости.

Я хочу указать вам на книгу Design Patterns для ответа на этот общий вопрос: p

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

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

IMO, это также помогает использовать динамический язык - позволяет настраивать основной код во время выполнения (когда это абсолютно необходимо). Я оценил, что расширяемость Mozilla работает таким образом при написании расширений Firefox.

Я думаю, что у вашего вопроса есть два аспекта:

Расширяемый дизайн системы (шаблоны проектирования, инверсия управления и другие архитектурные аспекты) ( http://www.martinfowler.com/articles/injection.html ). И, по крайней мере, для меня, да, эти шаблоны / методы не зависят от платформы / языка и могут рассматриваться как «общая процедура».

Теперь их реализация зависит от языка и платформы (например, в C/C++ у вас есть динамические библиотеки и т. Д.)

Было разработано несколько «фреймворков», чтобы дать вам среду программирования, которая обеспечивает возможность расширения / расширения, но, как отмечают некоторые другие люди, не сходите с ума, делая все подключаемым.

В мире Java хорошей спецификацией является OSGi ( http://en.wikipedia.org/wiki/OSGi ) с несколькими реализациями, лучшая из которых IMHO - Equinox ( http://www.eclipse.org/equinox/ )