Voglio essere in grado di avere un (piuttosto) grande FSM in cui posso eseguire il debug saltando a un punto e osservando l'esecuzione.
Ad esempio, diciamo che sto facendo un FSM che usa una certa probabilità se vado a sinistra o a destra a un incrocio. Forse ho un sacco di cose come "le persone che ho visto andare a sinistra" e "le persone che ho visto vanno bene".
Supponiamo che il semplice codice sopra sia simile a questo:
if (somethingA()) {
if (somethingB()) {
if (somethingX() && somethingY()) {
// ...
} else {
// ...
}
} else if (somethingC()) {
// ...
}
} else {
// ...
}
Inoltre, supponi che tutte le funzioni di qualcosa ... () siano basate sulla probabilità!
Il codice sopra è brutto, ma solo per illustrazione.
C'è qualche tipo di design che mi permetterebbe di andare arbitrariamente in un albero? Dato che sarebbe distribuito su più funzioni (di nuovo questo non è un FSM di dimensioni ridotte), un modello di progettazione potrebbe aiutarmi qui?
Idealmente vorrei sondare come funziona saltando fino al punto prima di somethingX() && somethingY()
se cambio alcuni parametri di probabilità per vedere come reagisce dopo, e vediamo come funziona andando da lì. Ad esempio, se ho 10 funzioni annidate come sopra, vorrei passare al layer 8, regolare la probabilità di una delle chiamate per vedere come funziona, e quindi dividere un gruppo di chiamate da quella.
Con questo intendo saltare al punto sopra, eseguire una simulazione, ma chiamare questa simulazione forse 1000 volte da quel punto (e vorrei eseguirlo il più rapidamente possibile e multithread).
L'unica soluzione che riesco a pensare è di aggiungere una sorta di POD (questo è C ++) e impostarlo in anticipo in modo da poter saltare esattamente dove voglio, come:
if (myStruct.jumpThroughA || somethingA()) {
if (myStruct.jumpThroughB || somethingB()) {
if (myStruct.jumpThroughXY || (somethingX() && somethingY())) {
// ...
} else {
// ...
}
} else if (myStruct.jumpThroughC || somethingC()) {
// ...
}
} else {
// ...
}
Tuttavia sono preoccupato che farò codice clusterfuck facendo questo (ma potrebbe essere la mia unica opzione). Voglio davvero evitare questo codice a meno che la mia schiena non sia contro il muro.
Inoltre, una cosa del genere sarebbe ottima per testare qualcosa di specifico, soprattutto perché la casualità avrà un ruolo in queste cose e mi piacerebbe testarlo forzandone alcuni rami (la mia idea di un PRNG prevedibile per i test potrebbe o potrebbe non renderlo ancora un rompicoglo).
UPDATE:
-
Ho bisogno di evitare di fare chiamate alla funzione poiché ho bisogno del codice per essere veloce, quindi valutarle in anticipo come per qui non è fattibile
-
Supponiamo che le funzioni qualcosa ... () abbiano effetti collaterali che sono progettati per aiutare ad aumentare la velocità di calcolo (es: qualcosaC () non dovrebbe essere calcolato se qualcosaB () restituisce true poiché invoca un costo molto elevato funzione)
-
Anche l'antipattern della freccia non risolve il mio caos "ramificazione in" di dover aggiungere più booleani a ogni livello per scendere rapidamente su un ramo di scelta