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

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

Мне интересно, какая общая процедура заключается в добавлении возможности расширения типа к системе, которую вы пишете, чтобы расширить функциональность с помощью какого-то 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, но я, возможно, не выглядел достаточно тяжело. В любом случае, вы можете предложить довольно прочную платформу для сценариев без особого труда. Это все еще не тривиально, но это дает вам очень хорошую базу для работы.