Nucleo funzionale per la progettazione del sistema di ascensori

5

Come può l'architettura "Functional Core / Imperative Shell" di Gary Bernhardt essere utilizzata per progettare software per un sistema di ascensori ?

In particolare, diciamo che ci sono alcuni ascensori, ognuno con pulsanti di chiamata (uno per piano). Ogni ascensore ha sensori che riportano velocità, posizione e stato dei pulsanti, e un controller che accetta istruzioni come salire, scendere, fermarsi. Inoltre ogni piano ha sensori che riportano lo stato dei pulsanti di chiamata su e giù.

Scegli ciò che è più facile per IO, come messaggi affidabili o altro. Scegli tutto ciò che è meglio in termini di concorrenza (multiprocessing, multithreading o solo codice asincrono).

Un sistema di ascensori avanzato basa le sue decisioni su qualcosa di più della semplice posizione attuale, la velocità di ogni ascensore e lo stato dei pulsanti di richiesta sui piani e all'interno dell'ascensore. In particolare, per fornire istruzioni agli ascensori, sarebbe necessario sapere quanto tempo fa accaddero vari eventi (per migliorare l'equità) e forse anche quello della storia recente (questo aiuterebbe a prevedere le richieste future).

Ma fornire così tante informazioni come input per una pura funzione sembra molto complicato.

Ci sto pensando male, oppure questo problema non è proprio adatto a quell'architettura?

Modifica: come ha sottolineato @ThomasKilian, il discorso a cui mi riferisco potrebbe non essere così noto come pensavo. Quindi lasciatemi espandere la domanda: mi interessa qualsiasi approccio in cui tutta la logica aziendale non banale è codificata per lo più usando lo stile di programmazione funzionale.

    
posta max 18.11.2016 - 21:28
fonte

1 risposta

2

Se incapsuli i tuoi dati in oggetti e decomponi adeguatamente le tue funzioni, penso che potresti facilmente utilizzare l'approccio core funzionale. Immagina un oggetto Floor per tenere traccia dei pulsanti premuti su ciascun piano, un oggetto Elevator che tiene traccia della velocità e dei pulsanti all'interno dell'ascensore. Per tenere traccia della cronologia, è possibile sfruttare l'immutabilità e spingere gli stati su una pila anziché sostituirli. L'interazione tra shell e core potrebbe essere simile a:

List<Stack<Elevator>> elevators;
List<Stack<Floor>> floors;

while(true) {
  orders = core(elevators, floors);

  runOrders(orders);

  foreach (elevator in elevators) {
    elevator.push(getNewState(elevator.peek()));
  }

  foreach (floor in floors) {
    floor.push(getNewState(floor.peek()));
  }
}

Il codice imperativo trasmette gli ordini agli ascensori della vita reale, recupera i loro nuovi stati e li spinge verso gli stacks. All'interno del nucleo, non è necessario nulla di non funzionale.

Sì, ci sono molti dati da passare, ma è perché hai bisogno di molti dati. Qualsiasi codice per gestire posizioni, velocità, pulsanti, cronologia, ecc. Sarà complicato. Avete qualche ragione per pensare che un'implementazione imperativa sarebbe più semplice di una funzionale funzionale referenzialmente trasparente?

    
risposta data 19.11.2016 - 01:33
fonte