Troppi parametri per il costruttore della classe di elaborazione dati

4

Ho un'applicazione concettualmente semplice: i dati arrivano come piccoli pacchetti crittografati, vengono decodificati e convalidati, alcuni vengono memorizzati nel database, alcune regole vengono applicate e una risposta può essere crittografata e inviata. I pacchetti arrivano a un ritmo elevato di centinaia di migliaia per thread al secondo, quindi le prestazioni sono una considerazione. Tralascio qui la maggior parte degli elementi prestazionali per concentrarmi sul design.

Elementi principali: i pacchetti arrivano in una coda e ogni thread del processore viene acquisito uno alla volta:

  1. assumere la proprietà di un singolo pacchetto in entrata (alla volta)
  2. decifrare
  3. usa una factory per costruire la classe di pacchetti appropriata
  4. il pacchetto si salva nel database (spesso più inserti)
  5. motore di regole eseguito da alcuni tipi di pacchetti, le azioni risultanti accodate
  6. pacchetto può generare 1 o più risposte a 1 o più destinatari

Un problema è che ogni thread del processore possiede una serie di istanze helper che vengono passate nel costruttore dei pacchetti. Quelle classi di helper sono spesso dolorose da creare (come la connessione al database), quindi non voglio che il pacchetto li costruisca. Durante la decrittazione accumulo informazioni sul pacchetto dal database, quindi voglio passare anche questo. Sono molti parametri.

Ho finito con 15 parametri per il costruttore PacketClass e in crescita. Sembra eccessivo, ma non riesco a vedere una soluzione elegante.

Il costruttore ha il seguente aspetto:

PacketClass(database, cryptoEngine, {more references} ...
   packetDataBlob, packetBlobSize, {packet source information}, 
   {database values passed rather than repeating lookups}...

A un certo punto ho intenzione di memorizzare nella cache le informazioni del database che vengono rilevate durante la decrittografia perché ci sarà solo un milione di record e quella ricerca sarà un collo di bottiglia. Ma per ora ci sono ~ 50 byte in 6 valori che vengono cercati per ogni pacchetto e poi passati al costruttore da una query SELECT. Una volta che la cache è operativa, quelli diventeranno un riferimento const singolo ma per ora non lo sono.

Opzioni:

  • crea tutti i riferimenti alle classi di utilità globali o globali thread secondo la tendenza IOC / localizzatore di servizi
  • passa un riferimento al thread / processore proprietario a ciascun pacchetto dando un collegamento abbastanza orribile
  • avvolgi i parametri in un paio di classi di dati e fai finta che non ci sia nulla da vedere.
  • dividere il costruttore PacketClass in costrutto-con-riferimenti e metodi initialise-with-data (ciò vale anche come soluzione?)
  • una soluzione geniale a cui non avevo pensato

Qualcuno può suggerire opzioni?

Robert Harvey suggerito nella chat dividere l'elaborazione in un PacketProcessorClass per ogni PacketClass in modo tale che comportamento e dati sono separati. In questo modo gran parte dell'elaborazione viene eseguita su PacketClass nel thread del processore piuttosto che all'interno del pacchetto come ora. Ho intenzione di lavorare attraverso questo progetto durante il fine settimana. Altre idee sono anche ben accette.

Nuovo design:

PacketClass( packetDataBlob, packetBlobSize, {packet source information}, 
   {database values passed rather than repeating lookups}...

PacketClassProcessor(database, cryptoEngine, {more references})
PacketClassProcessor.Process(Packet)

Considerazioni sulle prestazioni: potrebbe anche essere più veloce della configurazione corrente. Mi aspetto di poter memorizzare nella cache la maggior parte delle istanze ProcessorClass, quindi non c'è quel sovraccarico di costruzione. E PacketClass potrebbe diventare una struct in C, quindi di nuovo nessun overhead del costruttore tranne per le collezioni che contiene ... e posso memorizzare almeno una di queste (la "regole che si applicano a questo pacchetto").

(Ho modificato anche alcuni fluff)

    
posta Móż 21.11.2014 - 04:24
fonte

1 risposta

2

Sembra che tu abbia bisogno del classico refactoring Introduci oggetto parametro , che potrebbe essere il punto in cui Robert Harvey sta andando con PacketClassProcessor. Fondamentalmente, se un grande insieme di variabili viene passato tra più metodi, avvolgere tutti (o alcuni) di essi in una classe parametro.

    
risposta data 27.03.2015 - 14:58
fonte

Leggi altre domande sui tag