Considere um aplicativo que permita que os plug-ins reajam ao fluxo do programa.
Conheço duas maneiras de conseguir isso: ganchos e eventos
1. Ganchos
Use chamadas para funções vazias dentro do fluxo principal do programa. Essas funções podem ser substituídas por plugins.
Por exemplo, o Drupal CMS implementa ganchos disponíveis para módulos e temas. Aqui está um exemplo de como o hook é implementado em uma função 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;
// ...
}
Um módulo pode implementar uma modulename_file_copy($file, $source)
função que será chamada pelo module_invoke_all
in file_copy
. Após o término desta função, a file_copy
execução será retomada.
2. Eventos
Tenha os eventos de despacho do aplicativo, que podem ser ouvidos pelos plug-ins. Depois de receber um evento no qual foi inscrito, um plug-in interceptará o fluxo do programa e executará operações necessárias.
Por exemplo, um plug-in da galeria jQuery Fotorama implementa vários eventos . Como exemplo, aqui está uma parte de seu show
método que dispara o fotorama:show
evento.
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.]
};
Um script pode ouvir esse evento e fazer alguma coisa quando é acionado:
$('.fotorama').on(
'fotorama:show',
function (e, fotorama, extra) {
console.log(e.type + (extra.user ? ' after user’s touch' : ''));
console.log('transition duration: ' + extra.time);
}
);
QUESTÃO
Existem outras maneiras comuns de implementar esse comportamento de plug-in?
Caso contrário, quando se deve usar ganchos e quando se deve usar eventos? Considerando que o objetivo final é tornar o código mais fácil de ler e legível, tanto da perspectiva do desenvolvedor do aplicativo quanto do plugin?
fonte
Definitivamente eventos, ele permite a abstração necessária já no nível arquitetural.
Não espere que alguém que esteja escrevendo um plugin realmente o faça como documentado ou de alguma forma correto. Eu tenho mantido uma API bem documentada com milhões de usuários e posso dizer a partir de uma experiência muito dolorosa que basicamente ninguém nunca lê a documentação e quase ninguém usa a API corretamente.
Veja o seguinte exemplo com ganchos: Você tem um sistema em que 20 plugins estão em execução. Um desses plugins chama o
file_copy
método da maneira como está documentado e espera um resultado conforme documentado. Mas algum outro plugin conectou essa função e, portanto, um dos seguintes problemas causa uma falha ou mau funcionamento:Se você fizer o mesmo que acima com eventos com os mesmos problemas dentro desses plugins, acontece o seguinte:
fonte
A herança pode ser uma opção.
Além de ganchos, a herança não precisa de definições de método extras, e não há perda de desempenho para chamar o método vazio, caso não haja nada conectado.
Além de eventos, a herança também não precisa de código extra para invocação de eventos.
No entanto, a herança funciona melhor se houver apenas um plugin modificando um tipo de comportamento. Se você precisar de muitos plugins, o segundo precisará derivar do primeiro, etc., o que não é apropriado.
fonte
Definitivamente eventos. Permite que sua arquitetura seja mais escalável.
Imagine o que acontecerá se você precisar colocar seu plug-in em uma máquina separada, por exemplo. Usando eventos - você precisará modificar apenas uma pequena quantidade de código para tornar seus eventos baseados em rede.
fonte