Предложения по добавлению возможностей плагина?
Существует ли общая процедура программирования возможностей расширяемости в вашем коде?
Мне интересно, какая общая процедура заключается в добавлении возможности расширения типа к системе, которую вы пишете, чтобы расширить функциональность с помощью какого-то API плагина, а не изменять основной код системы.
Как правило, такие вещи зависят от языка, на котором была написана система, или существует общий метод для этого?
Ответы
Ответ 1
Это, как правило, то, что вам придется подвергать самому себе, поэтому да, это будет зависеть от языка, на котором написана ваша система (хотя часто можно писать обертки и для других языков).
Если, например, у вас была программа, написанная на C, для Windows, плагины будут написаны для вашей программы как библиотеки DLL. Во время выполнения вы вручную загружаете эти библиотеки и выставляете им какой-то интерфейс. Например, библиотеки DLL могут выставлять функцию gimme_the_interface()
, которая может принимать структуру, заполненную указателями на функции. Эти указатели функций позволят DLL совершать вызовы, регистрировать обратные вызовы и т.д.
Если бы вы были на С++, вы бы использовали DLL-систему, за исключением того, что вы, вероятно, передали бы указатель объекта вместо структуры, а объект реализовал бы интерфейс, обеспечивающий функциональность (выполнение той же функции, что и структура, но менее некрасиво). Для Java вы загружаете файлы классов по требованию вместо DLL, но основная идея будет одинаковой.
Во всех случаях вам необходимо определить стандартный интерфейс между вашим кодом и плагинами, чтобы вы могли инициализировать плагины, и поэтому плагины могут взаимодействовать с вами.
P.S. Если вы хотите увидеть хороший пример системы плагинов С++, ознакомьтесь с foobar2000 SDK. Я не использовал его довольно долго, но это было действительно хорошо сделано. Я предполагаю, что это все еще есть.
Ответ 2
В прошлом я использовал API-интерфейсы, основанные на событиях для плагинов. Вы можете вставлять крючки для плагинов, отправляя события и предоставляя доступ к состоянию приложения.
Например, если вы пишете приложение для блогов, вам может потребоваться поднять событие непосредственно перед тем, как новое сообщение будет сохранено в базе данных, и предоставит пост HTML плагину для изменения по мере необходимости.
Ответ 3
У меня возникает соблазн указать вам книгу Design Patterns для этого общего вопроса: p
Серьезно, я думаю, что ответ отрицательный. Вы не можете писать расширяемый код по умолчанию, он будет трудно записывать/продлевать и ужасно неэффективно (Mozilla начинала с идеи быть очень расширяемой, везде использовала XPCOM, и теперь они поняли, что это ошибка, и начали ее удалять где это не имеет смысла).
что имеет смысл сделать, это определить части вашей системы, которые могут быть значительно расширены и поддерживать надлежащий API для этих случаев (например, плагины поддержки языка в редакторе). Вы должны использовать соответствующие шаблоны, но конкретная реализация зависит от вашего выбора платформы/языка.
IMO, он также помогает использовать динамический язык - позволяет настроить основной код во время выполнения (когда это абсолютно необходимо). Я высоко оценил, что расширяемость Mozilla работает при написании расширений Firefox.
Ответ 4
Я думаю, что есть два аспекта вашего вопроса:
Конструкция расширяемой системы (шаблоны проектирования, инверсия элементов управления и другие архитектурные аспекты) (http://www.martinfowler.com/articles/injection.html). И, по крайней мере для меня, да, эти шаблоны/методы независимы от платформы/языка и могут рассматриваться как "общая процедура".
Теперь их реализация связана с языком и платформой (например, в C/С++ у вас есть материал динамической библиотеки и т.д.)
Несколько "фреймворков" были разработаны, чтобы дать вам среду программирования, которая обеспечивает возможность подключения/расширяемости, но, как говорят некоторые другие люди, не слишком сумасшедшая, чтобы сделать все подключаемым.
В мире Java хорошей спецификацией является OSGi (http://en.wikipedia.org/wiki/OSGi) с несколькими реализациями, лучшим из которых является ИМХО, являющееся Equinox (http://www.eclipse.org/equinox/)
Ответ 5
-
Узнайте, какие минимальные требования вы хотите разместить в плагине. Затем создайте один или несколько интерфейсов, которые автор должен реализовать для вашего кода, чтобы знать, когда и где выполнять код.
-
Создайте API, который автор может использовать для доступа к некоторым функциям вашего кода.
Вы также можете создать базовый класс, который должен наследовать автор. Это упростит подключение API. Затем используйте какое-то отражение для сканирования каталога и загрузите классы, которые вы найдете в соответствии с вашими требованиями.
Некоторые люди также создают язык сценариев для своей системы или реализуют интерпретатор для подмножества существующего языка. Это также возможный путь.
Нижняя строка: когда вы загружаете код, только ваше воображение должно быть в состоянии остановить вас.
Удачи.
Ответ 6
Если вы используете скомпилированный язык, такой как C или С++, может быть хорошей идеей посмотреть поддержку плагинов через языки сценариев. Оба Python и Lua - отличные языки, которые используются для script большого количества приложений (Civ4 и blender используют Python, Supreme Commander использует Lua и т.д.).
Если вы используете С++, проверьте библиотеку boost python. В противном случае python отправляет заголовки, которые могут использоваться в C, и делает довольно хорошую работу, документирующую API C/python. Документация казалась менее полной для Lua, но я, возможно, не выглядел достаточно тяжело. В любом случае, вы можете предложить довольно прочную платформу для сценариев без особого труда. Это все еще не тривиально, но это дает вам очень хорошую базу для работы.