Suggerimenti del motore delle regole per codice hard if-then-else

1

Domanda di ripubblicazione come post precedente sullo stesso L'argomento non era chiaro.

Attualmente la nostra applicazione finanziaria riceve più feed in formato csv dal client, solitamente ci sono da 100 a 5 milioni di righe di dati. Quando vengono elaborate queste informazioni, è necessario arricchire i dati e archiviarli, vengono eseguite varie ricerche e in base ai dati necessari per categorizzare o assegnare più valori.

Un esempio di mappatura è simile a

Firm     Category   Sub-Category   Code   Acct   = InternalCode( Enriched )
A         a1        sc1            c1     acc1   =   ACCT1
B                                         acc2   =   ACCT2
B         b1                                     =   ACCT3
B         b1        sc3            c3     acc4   =   ACCT4

Qui (dal feed di dati), se firm = B e category = b1, InternalCode è ACCT3, se firm = B e Acct = acc2, quindi InternalCode è ACCT2.

Attualmente tutti questi sono hard-coded in vari programmi con duplicazione e debito difficile da mantenere / tecnico. Vogliamo rimuovere la codifica hard in modo configurabile.

Esistono molte di queste ricerche e ogni ricerca ha centinaia di tali regole aziendali.

Qual è il modo migliore per rimuovere hard coding? Sto pensando di usare il motore delle regole ma non sono sicuro di quali criteri applicare per sceglierne uno per tale caso d'uso. Inoltre, ci sono altri metodi per spostare questo tipo di logica dal codice?

Grazie.

    
posta akumar 22.09.2018 - 05:44
fonte

4 risposte

1

Penso che sia importante realizzare prima i tuoi obiettivi - in genere non è solo una "miglior manutenibilità". Una motivazione comune alla rimozione delle regole codificate dal codice alla configurazione è spesso quella di spostare la responsabilità per mantenere le regole dal team degli sviluppatori ai team aziendali (e scommetto che anche qui è il tuo caso) .

Ciò significa che la configurazione e il mantenimento delle regole in alcuni file di configurazione dovrebbero essere meno complesse rispetto all'implementazione in codice e dovrebbero essere fattibili da alcune persone del team aziendale. Altrimenti una soluzione configurabile non ti porterà alcun beneficio.

Sfortunatamente, raramente c'è una soluzione "taglia unica" per questo. Probabilmente hai molti casi d'uso diversi, ognuno dei quali richiede un diverso livello di complessità. Consiglierei provare approcci diversi, iniziare con uno semplice e vedere come funziona. Ecco alcune idee

  1. In alcuni casi, l'utilizzo di una tabella di decisioni come quella mostrata nell'esempio può essere completamente sufficiente come configurazione. Metti la tabella in un foglio di calcolo o in un database (scegli ciò che preferisce il tuo business team) e scrivi un programma che valuta la tabella e elabora i dati secondo tali regole.

  2. Per alcuni casi, potrebbe essere ragionevole implementare la tua lingua specifica di dominio. Questo può essere molto semplice o può essere complesso come altri linguaggi di programmazione su vasta scala. (Ad esempio, l'ho fatto alcune volte usando un modulo tabulare, con una colonna per le precondizioni, una per le azioni e una per i parametri, che è un approccio molto semplice, facile da implementare ma ancora abbastanza potente per molti casi.) Quindi si può implementare un interprete per la DSL. Nota che la DSL deve rimanere abbastanza semplice da gestire i tuoi uomini d'affari (o almeno alcuni "utenti esperti").

    Per darti un altro esempio: una volta avevo alcuni utenti che non erano sviluppatori, ma avevo una certa esperienza con SQL. Hanno richiesto uno strumento di convalida per un database con > 100 regole di convalida e volevano gestirli da soli. Il modello di dati era abbastanza criptico, ma il team aziendale aveva una buona conoscenza della sua semantica, meglio di ogni altro nel nostro team di sviluppo. Li abbiamo trasformati in un foglio Excel in cui potevano memorizzare le parti rilevanti per un'istruzione SELECT da soli e definito qualcosa come "DSL" per elaborare i set di risultati in vari modi. Il programma che abbiamo dato loro poi ha letto gli SQL, li ha eseguiti contro il DB e ha interpretato i risultati secondo la DSL. La soluzione è ancora in produzione, nel corso degli anni, con zero requisiti di manutenzione per gli sviluppatori.

  3. Utilizzo di un motore di regole. Questa è una forma di "DSL predefinito, per uso generale" per il mantenimento delle regole. Potrebbe essere una buona soluzione per il tuo caso, ma comporta anche il rischio che tu abbia bisogno di specialisti per scrivere e mantenere le regole, finendo con una soluzione che può essere più difficile da mantenere e eseguire il debug rispetto al tuo sistema attuale (solo da persone diverse ). Vi consiglio di leggere tutte le risposte a questa vecchia domanda SO "Quando dovrebbe NON usi un motore di regole? " e verifica quali argomenti pro e contro si applicano alla tua situazione specifica.

risposta data 22.09.2018 - 09:56
fonte
0

Il modo sbagliato

Sarebbe tentato di dirti di inserire ogni mappatura in una tabella di database e interrogare fornendo tutti i campi rilevanti. Ciò tuttavia non tiene conto del fatto che le regole possono essere basate sulla corrispondenza parziale e che quando si trovano più regole di corrispondenza, il più specifico dovrebbe applicarsi:

Esempio:

Input data:                                  Output Explanations on rules

Firm     Category   Sub-Category   Code
B        b1         sc2            c3        ACCT3  (R2,R3 match but R3 is the most specific)
B        b1         sc3            c3        ACCT4  (R2,R3,R4 matches but R4 is the most specific) 
B        b2         sc3            c3        ACCT2  (only R2 matches, for B)

Soluzione 1: algoritmo di corrispondenza sofisticato per ciascuna mappatura

Naturalmente puoi elaborare la tabella di mappatura aggiungendo un valore di precedenza alla regola e generare una query più complessa che trovi tutti i candidati e prendi quella con la precedenza più alta.

Questo è soggetto a errori (generazione di query di Comlex, rischio di regole non ancora selezionate, necessità di definire la precedenza manuealmente). Inoltre, potrebbe portare a molte domande costose.

Soluzione 2: algoritmo di corrispondenza che utilizza mappature successive

Un altro approccio potrebbe essere quello di determinare un set di tabelle di mappatura e lasciare che il tuo motore di regole iterazioni attraverso condizioni successive, fermandosi ogni volta che viene trovata una regola corrispondente:

Mapping 1:  
Firm     Category   Sub-Category   Code   Acct   = InternalCode( Enriched )
A         a1        sc1            c1     acc1   =   ACCT1
B         b1        sc3            c3     acc4   =   ACCT4

Mapping 2:  
Firm     Category                                = InternalCode( Enriched )
B         b1                                     =   ACCT3

Mapping 3
Firm                                             = InternalCode( Enriched )
B                                         acc2   =   ACCT2

Questo tipo di approccio viene utilizzato nei motori di determinazione dei prezzi ad alte prestazioni (e ha anche portato al brevetto contenziosi che hanno concluso che si trattava di un approccio ben noto: disclaimer: non sono un avvocato, e questa è la mia comprensione personale e non la consulenza legale ).

Questo approccio può essere usato sia in un record per modo record (passando per ogni serie di mappature per ogni record). Ma può anche essere usato in un modo più efficiente se hai caricato il tuo CSV in un database, usando alcune istruzioni di aggiornamento successive che non aggiornano i valori dell'account già riempiti dai passaggi precedenti.

Altre soluzioni

Un altro approccio potrebbe essere utilizzare un motore di regole più sofisticato e tradurre tutto il tuo se-then-else in business regole. Il vantaggio è che non è necessario determinare le tabelle di mappaggio come si è fatto. Non è necessario pensare alle dipendenze di mapping (ad esempio se su ogf il campo di mapping è in realtà determinato da una mappatura precedente). È anche facile aggiungere nuove regole.

L'inconveniente è che il motore di regole è invocato per ogni record CSV. Quindi potrebbe essere più pesante dell'approccio basato su tabelle (vedi soluzione 2). Inoltre, è difficile per lo scrittore di regole comprendere l'interazione tra diversi tipi di regole.

Se non vuoi utilizzare un motore basato su regole esistente e svilupparne uno tuo, potresti essere interessato a questo SE domanda .

    
risposta data 23.09.2018 - 20:17
fonte
-1

È possibile rendere centralizzati i mapping mantenendoli nel database ed esponendo la funzionalità get / update / delete / edit di un singolo / alcuni / tutti i mapping tramite RESTful API. La mappatura può essere recuperata prima dell'elaborazione di ciascun batch.

    
risposta data 22.09.2018 - 09:26
fonte
-1

Penso che la soluzione semplice e veloce sia quella di convertire le condizioni e le corrispondenti ricerche nel database Redis in questo modo:

In questo scenario è necessario considerare tutte le possibili condizioni per una volta e impostare il tema in Redis e per la ricerca è possibile utilizzare direttamente i client Redis o scrivere un servizio Web o altro.

Il vantaggio di questo metodo è la complessità temporale delle operazioni Imposta e Ottieni in Redis, che è O (1) e puoi recuperare i valori corrispondenti ai tasti molto velocemente.

    
risposta data 22.09.2018 - 09:42
fonte