Modelli di progettazione per l'elaborazione / la manipolazione dei dati

4

A volte quando scrivo una classe o un pezzo di codice che deve occuparsi di analisi o elaborazione dei dati, devo chiedermi se potrebbe esserci una soluzione migliore al problema.

Esempio 1: In un recente esame abbiamo dovuto scrivere una simulazione per un servizio di car sharing. Ci è stata data una città che è stata divisa in diversi (n * n) distretti. Ogni distretto ha lavorato in modo indipendente e ha avuto due funzioni. Il primo rappresentava la quantità di auto che erano state prese in prestito e la seconda la quantità di auto che erano state restituite (in questo specifico distretto, all'ora). Ora dovevamo calcolare alcuni valori per ogni distretto.

Ovviamente avevo una classe di città e una classe di distretto. La domanda è: Dove trovo la parte di simulazione? Potrei scrivere una funzione all'interno della classe distrettuale o scrivere una classe dedicata (simulatore) che gestisca tutta l'elaborazione.

Quindi in pratica:

City.Simulate()
   foreach District in City
        District.Simulate
return results

o

Simulator(City)
   Simulate
      Get all district objects
         do simulation & collect results
   return results

Alla fine ho deciso di andare con la prima opzione, ma non sono davvero soddisfatto di questo approccio.

Esempio 2: Forse il problema si chiarisce con questo esempio. Attualmente sto scrivendo un broker MQTT e sto lavorando al parser di pacchetti. Esiste una classe per ogni tipo di pacchetto (Connect, Publish, Subscribe, ecc.). Dove devo eseguire l'analisi?

Per questo progetto ho creato una classe dedicata per l'analisi che ha una funzione per ogni tipo. Tuttavia, in un progetto precedente (simile), ogni classe di pacchetti ha fornito una funzione di analisi personalizzata.

Quindi una domanda più generale sarebbe: A che punto posso esternalizzare l'elaborazione dei dati / a quale punto posso elaborare i dati all'interno della classe stessa?

    
posta Camo 12.06.2017 - 14:50
fonte

2 risposte

3

Avendo lavorato su questo tipo di problemi molte volte, vado sempre con l'opzione n. 2, per due motivi principali:

1. Lo considero più vero per SRP

"Simulare" è fondamentalmente una cosa sua. Se dovessi porre la domanda "cosa fa questa lezione", la classe city nella tua opzione # 1 ha due risposte: "tieni traccia dei dati relativi alla città e calcola le statistiche relative a quei dati". Quel "e" implica che viola l'SRP. Questo non vuol dire che sia un'idea terribile e non dovrebbe mai essere fatto in questo modo, ma dai principi di base dell'OOP direi che è meglio separarlo nella sua stessa classe. Ora per una ragione più pratica:

2. Simulazioni, statistiche, calcoli, ecc. Cambiano spesso .

Questa è la ragione principale per me. In questo momento la tua simulazione sta calcolando cose come "Quali distretti sono in eccesso quando?". Questo è abbastanza semplice, e se vivesse nella tua classe di città difficilmente sarebbe la fine del mondo. Ma cosa succede se decidi per strada che hai bisogno di più statistiche? In un progetto del mondo reale è garantito che questo genere di cose succederà. Entro la fine dell'anno eseguirai una dozzina di calcoli statistici diversi e le simulazioni potrebbero variare da città a città. In tal caso, potresti immaginare di avere una classe simulation diversa per ogni diverso tipo di statistiche che viene calcolata e persino avere classi specifiche per determinate città. Questo tipo di situazione sarebbe impossibile da gestire se tutto fosse vissuto all'interno della classe della tua città, ma molto facile da gestire una volta che inizi a suddividere le cose in classi separate.

Quindi la risposta breve è che per l'attuale livello di problema che stai risolvendo, in entrambi i casi funziona bene (praticamente parlando). Tuttavia, nel lungo periodo, i calcoli statistici e di simulazione sono il loro genere di cose e dovrebbero vivere nella loro gerarchia di classi per la massima riusabilità e manutenibilità.

    
risposta data 12.06.2017 - 15:43
fonte
0

Obviously I had a City-class and a District-class. The question is: Where do i so the simulation part? I could write a function inside the district class or I could write a dedicated (simulator-)class which handles all the processing.

Per come la vedo io, un Distretto è responsabile solo del calcolo delle informazioni relative alle informazioni che ha nella propria classe. Questo può a volte estendersi all'esecuzione di calcoli con altre istanze della sua stessa classe, per esempio, confrontando o testando l'uguaglianza, ma per la maggior parte, non dovrebbe interessare nulla al di fuori del suo mondo (o distretto in questo caso).

Quindi sarebbe compito della città eseguire il calcolo. Probabilmente si potrebbe pensare che la città fosse solo un contenitore di istanze distrettuali, e se la città si fosse impantanata di molte logiche, avrei seriamente pensato di separare City, il container e City, il simulatore. In effetti, CitySimulator potrebbe essere un nome appropriato per tale classe. Ma come hai detto, questo è un semplice esempio, quindi solo City dovrebbe essere sufficiente.

Example 2: Maybe the problem gets clearer with this example. I'm currently writing an MQTT Broker and am currently working on the packet parser. There is one class for each packet type (Connect, Publish, Subscribe, etc.). Where do I do the parsing?

Se l'analisi è abbastanza semplice, devi semplicemente scrivere una classe Parser che determina il tipo di messaggio e passa il resto del messaggio a metodi separati, uno per ciascun tipo per analizzare il resto. Sebbene, in un esame, questa non sia la risposta che probabilmente stanno cercando.

Potresti creare una classe Parser che non fa nulla, tranne chiamare un elenco di classi che gestiscono ciascun tipo di messaggio, con due metodi: canHandle e handle. canHandle viene chiamato per primo e la classe che gestisce quel particolare tipo deve restituire true solo se è un messaggio di quel tipo, dopo di che viene chiamato handle che, se fatto correttamente, significa che ogni classe gestisce il proprio tipo di messaggio senza sapere nulla sul altri, riducendo efficacemente l'accoppiamento tra loro e la classe Parser.

    
risposta data 12.06.2017 - 16:32
fonte