Рассмотрим приложение, которое позволяет плагинам реагировать на ход программы.
Я знаю 2 способа добиться этого: хуки и события
1. Крючки
Используйте вызовы для очистки функций внутри основного потока программы. Эти функции могут быть переопределены плагинами.
Например, Drupal CMS реализует хуки, которые доступны для модулей и тем. Вот пример того, как ловушка реализована в функции file_copy .
function file_copy(stdClass $source, $destination = NULL, $replace = FILE_EXISTS_RENAME) {
// ... [File copying routine]
// Inform modules that the file has been copied.
module_invoke_all('file_copy', $file, $source);
return $file;
// ...
}
Модуль может реализовать modulename_file_copy($file, $source)
функцию, которая будет вызываться функцией module_invoke_all
in file_copy
. После завершения этой функции file_copy
выполнение возобновится.
2. События
Получите от приложения события отправки, которые могут прослушиваться плагинами. После получения события, на которое он подписан, плагин будет перехватывать поток программы и выполнять необходимые операции.
Например, плагин галереи jQuery Fotorama реализует несколько событий . Например, вот часть его show
метода, который запускает fotorama:show
событие.
that.show = function (options) {
// ... [show the new frame]
// [fire the event]
options.reset || triggerEvent('show', {
user: options.user,
time: time
});
// ... [do lots of other stuff with navigation bars, etc.]
};
Скрипт может прослушивать это событие и что-то делать при его запуске:
$('.fotorama').on(
'fotorama:show',
function (e, fotorama, extra) {
console.log(e.type + (extra.user ? ' after user’s touch' : ''));
console.log('transition duration: ' + extra.time);
}
);
ВОПРОС
Существуют ли другие основные способы реализации такого поведения плагина?
Если нет, то когда следует использовать хуки и когда следует использовать события? Учитывая конечную цель - сделать код более понятным и читаемым как с точки зрения приложения, так и с точки зрения разработчика плагина?
Определенно события, это позволяет необходимую абстракцию уже на архитектурном уровне.
Не ожидайте, что кто-либо, пишущий плагин, на самом деле делает это, как задокументировано или каким-либо образом правильно. Я поддерживаю хорошо документированный API с миллионами пользователей, и я могу сказать вам по очень болезненному опыту, что практически никто никогда не читает документацию и почти никто не использует API правильно.
Возьмем следующий пример с хуками: у вас есть система, в которой запущено 20 плагинов. Один из этих плагинов вызывает
file_copy
метод так, как он задокументирован, и ожидает результат в том виде, в котором он задокументирован. Но какой-то другой плагин перехватил эту функцию, и поэтому одна из следующих проблем вызывает сбой или неисправность:Если вы делаете то же, что и выше, с событиями с теми же проблемами внутри этих плагинов, происходит следующее:
источник
Наследование может быть вариантом.
Помимо хуков, наследование не требует дополнительных определений методов, и при вызове пустого метода не происходит потери производительности в случае, если ничего не подключено.
Помимо событий, наследование также не требует дополнительного кода для вызова события.
Однако наследование работает лучше всего, если есть только один плагин, модифицирующий один тип поведения. Если вам нужно много плагинов, второй должен быть производным от первого и т. Д., Что не подходит.
источник
Определенно события. Это позволяет вашей архитектуре быть более масштабируемой.
Представьте, что произойдет, если вам нужно, например, разместить свой плагин на отдельном компьютере. Использование событий - вам нужно всего лишь изменить небольшую часть кода, чтобы ваши события основывались на сети.
источник