TheCodeNaked

Parte 4 - Interpretação via JSON: Plugins configuráveis com dicionários de ações. (Copy)

Depois de entender o poder da abstração e dos plugins, chegou a hora de subir mais um degrau. E se, em vez de compilar as regras do sistema, você as carregasse de um arquivo JSON? E se as ações fossem apenas nomes ligados a comportamentos, como num mini interpretador?

Bem-vindo à próxima fronteira: sistemas configuráveis por dicionários de ações.

Um mini interpretador

Vamos imaginar que seu sistema precisa executar diferentes tarefas com base em um plano de ações definido por um cliente. Esse plano vem em um JSON como:

[
  { "acao": "EnviarEmail", "para": "cliente@exemplo.com" },
  { "acao": "GerarPDF", "arquivo": "relatorio.pdf" },
  { "acao": "AtualizarStatus", "id": 123, "status": "concluido" }
]

Em vez de codificar essas três ações na lógica principal, você pode registrá-las como comandos:

type
  TActionProc = reference to procedure(Params: TJSONObject);

var
  ActionMap: TDictionary<string, TActionProc>;

procedure RegisterAction(Name: string; Proc: TActionProc);
begin
  ActionMap.AddOrSetValue(Name, Proc);
end;

Registrando as ações

RegisterAction('EnviarEmail',
  procedure(Params: TJSONObject)
  begin
    SendEmail(Params.GetValue('para').Value);
  end);

RegisterAction('GerarPDF',
  procedure(Params: TJSONObject)
  begin
    ExportPDF(Params.GetValue('arquivo').Value);
  end);

Executando

procedure ExecuteActions(ALista: TJSONArray);
var
  Item: TJSONValue;
  Acao: string;
  Params: TJSONObject;
begin
  for Item in ALista do
  begin
    Params := Item as TJSONObject;
    Acao := Params.GetValue('acao').Value;
    if ActionMap.ContainsKey(Acao) then
      ActionMap[Acao](Params)
    else
      ShowMessage('Ação desconhecida: ' + Acao);
  end;
end;

O que você ganhou com isso?

  • Ações podem ser definidas por um cliente, consultor ou outro sistema
  • Não há recompilação
  • Código desacoplado e dinâmico
  • Possibilidade de fallback para ações não reconhecidas

E se a ação não existir?

Você pode criar uma ação "Default":

ActionMap.AddOrSetValue('DEFAULT',
  procedure(Params: TJSONObject)
  begin
    Log('Ação desconhecida: ' + Params.GetValue('acao').Value);
  end);

E então mudar o bloco de execução:

if ActionMap.ContainsKey(Acao) then
  ActionMap[Acao](Params)
else
  ActionMap['DEFAULT'](Params);

Isso é ou não é acoplamento?

Sim. Mas agora você está acoplado a nomes de ações, não a implementações. A fronteira foi movida do código para o JSON. E isso muda tudo.

Possibilidades futuras

  • Carregar plugins de DLLs e registrar dinamicamente
  • Criar uma linguagem declarativa própria
  • Criar filtros e condicionais dentro do JSON
  • Validar sequências de execução

Conclusão

A ideia de dicionários de ações transforma o seu código em uma engine.
E uma engine bem feita pode durar décadas, mesmo que as regras mudem todo mês.

A capacidade de interpretar comportamentos, e não apenas codificá-los, é o que separa um sistema comum de uma verdadeira plataforma.


Próximo artigo sugerido: "Condicionais no JSON: tomando decisões fora do código"

Sobre o autor

TheCodeNaked

No TheCodeNaked, programar é consequência, não ponto de partida. Antes do código, vem a dúvida, a análise, o contexto. Não seguimos fórmulas — questionamos. Criar software é pensar com clareza. O resto é só digitação.

TheCodeNaked

Criar com clareza. Codificar com intenção.

TheCodeNaked

Ótimo! Você se inscreveu com sucesso.

Bem-vindo de volta! Você acessou com sucesso.

Você se inscreveu com sucesso o TheCodeNaked.

Sucesso! Verifique seu e-mail para acessar com o link mágico.

As suas informações de faturamento foram atualizadas.

Seu pagamento não foi atualizado