Interagimos com alguma Arquitetura de Plugin quase todo dia, mas raramente percebemos sua existência.
Afinal, os plugins estão presentes em:
- Aplicativos baseados em produto (como o VS Code ou qualquer navegador que possa ser personalizado com adição de extensões);
- E aplicativos baseados em negócio (onde as regras de negócio e processamento de dados podem variar, por exemplo, de acordo com o país).
A ideia é simples… Ser capaz de conectar ou adicionar recursos a um sistema existente, sem o sistema saber dos detalhes de implementação.
Portanto continue lendo esse artigo para entender melhor a Arquitetura de Plugin e elevar o seu código para outro nível:
Como funciona a Arquitetura de Plugin?
A Arquitetura de Plugin consiste em 2 componentes:
- O sistema principal;
- E os módulos de plugin;
O ideia central é permitir a adição de novas funcionalidades ao sistema principal através dos plugins.
Assim você constrói um aplicativo com:
- Fácil extensibilidade;
- Maior flexibilidade;
- E isolamento entre seus recursos.
O resultado disso tudo é uma lógica de processamento personalizada.
Em resumo, as regras específicas (de uma dada situação) são separadas do sistema principal (que é executado em todas as situações).
E, em qualquer momento, podemos adicionar, remover e alterar plugins existentes com pouco ou nenhum efeito no resto do sistema principal ou em outros módulos de plugin.
O que é o Sistema Principal?
Ele define como o sistema opera e a lógica básica de negócios. Não há implementação específica, nem personalização.
Por exemplo, um fluxo de trabalho genérico, a forma como o fluxo de dados é definido dentro do aplicativo.
Cavando um pouco mais fundo, o sistema principal também lida com regras especiais e processamento condicional complexo. São tarefas que precisam ser aplicadas, independente do plugin de extensão.
Além disso, ele contém o código comum que pode (ou precisa) ser usado por vários plugins. Como uma maneira de se livrar de código duplicado e ter uma única fonte para tarefas importantes.
Ou seja, se 2 plugins fazem o log das transações e falhas, o sistema principal deve fornecer essa função de logger como parte dele.
Sem mencionar outras funções como:
- Segurança;
- Controle de versão;
- Componentes de interface do usuário;
- Acesso ao banco de dados;
- E cache.
O que são os Módulos de Plugin?
Os plugins são componentes isolados, independentes, que contêm código customizado e processamento específico.
Dessa forma, aprimora ou estende o sistema principal para produzir funcionalidades adicionais.
E apesar dos módulos de plugin serem independentes, alguns podem exigir se comunicar com outros plugins e por isso assumem a existência deles no sistema.
Porém é importante manter a comunicação e a dependência entre plugins o mínimo possível.
Como o Sistema Principal se relaciona com os Plugins
O sistema principal precisa saber de 2 coisas:
- Quais são os módulos plugin disponíveis;
- E como chegar até eles.
Para isso o sistema principal declara pontos de extensão nos quais os plugins podem se conectar. Esses pontos de extensão, também chamados de ganchos, geralmente representam o ciclo de vida do sistema.
E assim, cada plugin se registra no sistema, passando algumas informações como:
- Nome;
- Protocolo de comunicação;
- Dados de entrada e saída;
- Formato dos dados;
- E os ganchos dos pontos de extensão.
Note que você precisa de uma interface bem definida entre o sistema e os plugins.
Como o sistema principal se conecta a esses plugins, depende do tipo de aplicativo sendo construído e em suas necessidades específicas (por exemplo, se é uma implantação única ou distribuída).
Veja o arquivo: Um rápido vislumbre das diferentes maneiras de conectar 2 componentes
Configurações
Agora você já deve ter notado que esses plugins precisam:
- Se anunciar no sistema principal;
- Aproveitar os pontos de extensão;
- E passar algumas informações.
Isso traz a ideia de configuração…
Ou seja, a cola, o ponto de contrato, pelo qual anexamos um plugin ao sistema principal. Onde tudo mencionado acima (pontos de extensão, protocolo de comunicação, etc) é definido.
// Este plug-in se conecta ao ciclo de vida do sistema principal
// e salva os eventos de atividades diárias emitidas
// pelo núcleo em um banco de dados.
core.registerPlugin({
name: 'track-my-activities',
port: 8081,
hooks: {
wakeup: function (time) {
saveTime("Woke up at: " + time);
},
work: function (time) {
saveTime("Started work at: " + time);
},
exercise: function (time) {
saveTime("Exercising at: " + time);
}
}
});
As configurações fornecem agilidade, além de permitir visualizar como cada plugin funciona. Talvez até seu fluxo dos dados.
Se “colar” um plugin no sistema principal é uma “dor de cabeça” por ter uma interface incompatível, é comum criar um adaptador entre o plugin e o sistema principal.
Assim o núcleo não precisa de um código especializado para cada plugin incompatível.
Como armazenar as configurações?
Por fim, as configurações podem ser armazenadas:
- No próprio código;
- Passadas para uma ferramenta CLI;
- Ou armazenadas no banco de dados.
Além disso, podem ser escritas em vários idiomas como: YAML, TOML, JS, JSON, XML, etc.
Porém seja qual for o idioma escolhido, você precisa ser capaz de fazer coisas como:
- Comentários;
- Condições;
- Validações;
- Loops;
- Ou o que for necessário.
Claramente, isso não é possível com o JSON.
Você também pode construir uma pequena ferramenta para validar essas configurações.
Uma vs Várias instâncias
Mencionamos dois casos de uso comuns… Os aplicativos baseados em produto e os baseados em negócio.
Adicionar plugins e extensões ao navegador é algo comum. Temos um sistema principal (o navegador) e os plugins podem ser anexados a ele.
Por outro lado podemos ter várias instâncias do sistema principal, como em grandes aplicativos de negócio.
Nesse caso, cada instância estende o núcleo e adiciona um ou mais plugins a ele.
No exemplo do navegador, isso significa ter vários navegadores, cada um com seu próprio conjunto de recursos.
Então possuímos vários aplicativos que estendem o sistema principal, cada um trabalhando por conta própria, totalmente independente.
Outros padrões
Esse padrão resolve um problema específico… Portanto pode formar toda a arquitetura, fazer parte ou usar junto com outros padrões.
Por exemplo, você tem uma arquitetura em camadas, onde a arquitetura de plugin está incorporada dentro dela.
Outro exemplo seria: uma arquitetura baseada em componentes (cliente, pedido, pagamento, etc). Onde os componentes são partes do sistema principal.
Analise da Arquitetura de Plugin
A natureza dessa arquitetura vem com muitas vantagens…
Por exemplo, os plugins são independentes, isso dá agilidade para alterar, remover e adicionar novas extensões.
O que facilita quando você tem vários serviços (em módulos de plugin) conversando uns com os outros e lidando com falhas.
Além disso, dependendo de como o padrão é implementado, cada plugin pode ser implantado, testado e dimensionado separadamente.
No entanto, há uma grande armadilha! O sistema principal em si…
Quando você altera o sistema principal, corre o risco de quebrar ou alterar o comportamento do plugin. E por isso requer um design atencioso no início.
E atenção! Tudo o que mencionamos nesse artigo contribui para a complexidade na hora de implementar esse padrão.
Desde a definição dos possíveis pontos de extensão, conexão do plugin ao núcleo, controle de versão, regras de negócios aplicadas pelo núcleo…
Então, se você não tomar cuidado, acabará com:
- Um sistema principal complexo;
- Cheio de condições
if-else
; - A independência de plugins não será mais uma característica;
- E alterar uma linha de código exigirá um arsenal de analistas, desenvolvedores e testadores.
Hey,
o que você achou deste conteúdo? Conte nos comentários.
Eu estava um pouco perdido em como implementar uma Arquitetura de Plugin e tive dificuldade de achar um artigo explicando…
Então li esse artigo do Omar Elgabry e ele me ajudou muito a entender como funciona essa Arquitetura e a partir dai consegui seguir os próximos passos.
Por isso decidi publicar essa tradução e adaptação do artigo do Omar Elgabry.
Outras Referências:
DevMidia
peerspot
marcobaccaro
freecontent