Pular para conteúdo

Aula 17 - Modelagem de Decisões de Negócio (DMN 1.3) e Tabelas 📊

Objetivo Pedagógico

Objetivo: Compreender a especificação internacional DMN 1.3 mantida pela OMG, modelar Requisitos de Decisão (DRD), estruturar Tabelas de Decisão com políticas de acerto e aplicar expressões FEEL (Friendly Enough Expression Language).


📑 1. Fundamentos Teóricos & Análise Técnica

No desenvolvimento de sistemas corporativos, as regras e decisões de negócio frequentemente acabavam soterradas dentro de milhares de linhas de código imperativo (if/else e switch), tornando qualquer alteração regulatória ou mercadológica lenta, onerosa e suscetível a erros humanos.

A Decision Model and Notation (DMN 1.3 - OMG) estabelece um padrão formal aberto para representação visual e execução computacional direta de decisões: 1. Decision Requirements Diagrams (DRD): - Modela o grafo de dependências entre decisões de negócio: - Decisão (Retângulo): A determinação de uma saída lógica com base em entradas e lógica decisória. - Dados de Entrada (Oval / Canto Arredondado): Informações externas alimentadas na decisão. - Conhecimento de Negócio (Retângulo com lados recortados): Funções de decisão encapsuladas e reutilizáveis (Business Knowledge Model - BKM). - Fonte de Conhecimento (Forma ondulada): Leis, regulamentações do Banco Central ou políticas internas que fundamentam a decisão. 2. Tabelas de Decisão e Políticas de Acerto (Hit Policies): - Unique (U): Apenas uma única regra pode ser satisfeita; as condições de entrada devem ser mutualmente exclusivas. - First (F): A primeira regra satisfeita de cima para baixo determina o resultado (ordenação relevante). - Collect (C): Múltiplas regras podem ser satisfeitas, retornando uma lista agregada (soma, contagem, mínimo, máximo). 3. FEEL (Friendly Enough Expression Language): - Linguagem de expressão padronizada pelo DMN para manipulação de intervalos numéricos ([18..65]), listas, datas e operadores lógicos declarativos.

📐 Arquitetura Conceitual & Diagrama de Fluxo

graph TD
    InputData1["Dados: Score de Crédito (300..1000)"] --> Decision["Decisão: Aprovação de Empréstimo"]
    InputData2["Dados: Renda Mensal Declarada"] --> Decision
    Source["Normativa Compliance BACEN"] --> Decision
    Decision --> DecisionTable["Tabela de Decisão DMN (Hit Policy: Unique)"]
    DecisionTable --> Out["Saída Estruturada: {status: 'APROVADO', taxa: 1.85}"]
    style InputData1 fill:#e1f5fe,stroke:#01579b
    style InputData2 fill:#e1f5fe,stroke:#01579b
    style Source fill:#ffebee,stroke:#c62828
    style Decision fill:#fff3e0,stroke:#e65100
    style DecisionTable fill:#f3e5f5,stroke:#7b1fa2
    style Out fill:#e8f5e9,stroke:#2e7d32

🔍 Pilares e Diretrizes Técnicas

Nesta unidade, aprofundamos os seguintes conceitos fundamentais: - Desacoplamento entre Lógica e Código: As decisões vivem em modelos XML interoperáveis que analistas de negócio podem inspecionar e editar sem recompilar a aplicação. - Determinismo Matemático com Hit Policy Unique: Garante formalmente que nenhuma combinação de entrada produza ambiguidade de resultados. - Expressividade Padronizada com FEEL: Sintaxe amigável para operadores booleanos e de intervalos que dispensa linguagens de script proprietárias. - Rastreabilidade e Compliance Regulatório: Auditabilidade total da árvore de raciocínio lógico perante órgãos fiscalizadores.


🛠️ 2. Implementação Prática em DMN 1.3 (Decision Model and Notation) e FEEL

Abaixo está a implementação técnica de referência, estruturada com padrões de engenharia de software e foco em robustez:

// credito_aprovacao.dmn (Definição XML DMN 1.3 de Tabela de Decisão)
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="https://www.omg.org/spec/DMN/20191111/MODEL/" 
             id="Def_Credito" name="DecisaoAprovacaoCredito" namespace="http://portal.empresa/dmn">
  <decision id="DecisaoScore" name="Avaliar Risco de Credito">
    <decisionTable id="Tabela_Score" hitPolicy="UNIQUE">
      <input id="In_Score" label="Score Serasa">
        <inputExpression id="Exp_Score" typeRef="integer">
          <text>cliente.score</text>
        </inputExpression>
      </input>
      <input id="In_Renda" label="Renda Mensal">
        <inputExpression id="Exp_Renda" typeRef="number">
          <text>cliente.renda</text>
        </inputExpression>
      </input>
      <output id="Out_Status" label="Status Decisao" name="status" typeRef="string" />
      <output id="Out_Taxa" label="Taxa Mensal (%)" name="taxa" typeRef="number" />

      <!-- Regra 1: Alto Score e Boa Renda -->
      <rule id="Regra_1">
        <inputEntry id="In1_1"><text>&gt;= 750</text></inputEntry>
        <inputEntry id="In1_2"><text>&gt;= 5000</text></inputEntry>
        <outputEntry id="Out1_1"><text>"APROVADO_VIP"</text></outputEntry>
        <outputEntry id="Out1_2"><text>1.19</text></outputEntry>
      </rule>

      <!-- Regra 2: Score Médio -->
      <rule id="Regra_2">
        <inputEntry id="In2_1"><text>[500..749]</text></inputEntry>
        <inputEntry id="In2_2"><text>&gt;= 3000</text></inputEntry>
        <outputEntry id="Out2_1"><text>"APROVADO_PADRAO"</text></outputEntry>
        <outputEntry id="Out2_2"><text>1.89</text></outputEntry>
      </rule>

      <!-- Regra 3: Score Baixo -->
      <rule id="Regra_3">
        <inputEntry id="In3_1"><text>&lt; 500</text></inputEntry>
        <inputEntry id="In3_2"><text>-</text></inputEntry>
        <outputEntry id="Out3_1"><text>"REJEITADO_SCORE"</text></outputEntry>
        <outputEntry id="Out3_2"><text>0.0</text></outputEntry>
      </rule>
    </decisionTable>
  </decision>
</definitions>

💡 Análise Passo a Passo do Código

  1. Configuração hitPolicy="UNIQUE": Assegura que uma única regra seja executada, impedindo cálculos de taxa conflitantes.
  2. Intervalos com FEEL ([500..749]): Expressa faixas inclusivas de números com clareza tipográfica padronizada.
  3. Entrada Coringa (-): Indica que a regra independe do valor da coluna de renda caso o score seja inferior a 500.

🎯 3. Próximos Passos & Sequência Didática