2013-01-05 9 views
19

Dal mio precedente question ho capito che Rails crea un'istanza di controller per ogni richiesta.Perché Rails crea un controller per ogni richiesta?

La mia domanda è, perché questo argomento è legato alla progettazione del progetto su cui sto lavorando:

Perché Rails crea una nuova istanza di

class SomeController < ApplicationController; end 

per elaborare ogni richiesta in arrivo? Perché non creare solo oggetti singleton e inoltrare richieste a questo? Questo sembra più efficiente in quanto non sprecheremo risorse per l'allocazione e la pulizia degli oggetti per la richiesta?

+1

Buona domanda, dovresti chiedere a DHH a riguardo :) Ma penso che il punto principale sia isolare assolutamente un ambiente con un altro. Perché altrimenti il ​​sistema deve spendere più potenza di elaborazione per la logica di distribuzione. imho –

+3

Perché è più facile ragionare sul codice quando non c'è il rischio di stompare sui dati di un'altra richiesta. –

+0

Nessuna sorpresa, ma sembra che Grails faccia la stessa cosa. –

risposta

32

Il sovraccarico di istanziare una nuova istanza del controller è insignificante e significa che non vi è uno stato accidentalmente condiviso tra due richieste completamente indipendenti. Qualsiasi "risparmio" nel tempo del processore sarebbe più che compensato dalla possibilità di produrre bachi devastanti.

Ricordare che i controller sono per la memorizzazione dello stato specifico della richiesta. Riutilizzare i controller richiederebbe il reset di ogni @variable che avresti impostato, all'inizio di ogni azione. In caso contrario, qualcosa come @is_admin = true potrebbe essere impostato e mai cancellato. I bug meno elaborati che introdurrai in realtà sarebbero molto più sottili e prosciugati nei tempi di sviluppo.

Stai vedendo ottimizzazioni dove non ce ne sono. Qualcosa deve mantenere lo stato e ripristinarlo tra le richieste, oppure si ha questo incubo di stato accidentalmente condiviso. Se si persistono istanze di controller tra richieste, si sta semplicemente spingendo il processo di mantenimento/ripristino dello stato verso un livello inferiore, dove probabilmente la risposta sarà per creare un'istanza nuova di una classe di gestione dello stato per ogni richiesta. I computer sono molto buoni nell'assegnazione e nella liberazione delle risorse, quindi mai preoccuparsi di ciò finché non si è effettivamente a conoscenza che si tratta di un collo di bottiglia. In questo caso, istanziare un nuovo controller per ogni richiesta è facilmente la scelta corretta.

Nel caso di rotaie, essendo in grado di utilizzare @variable = value è una vittoria importante da un punto di stand-codice purezza e usabilità, e questo più o meno risulta necessario per scartando ogni istanza di un controllore quando la richiesta viene completata.

+2

Beh ... non è tanto che '@ foo' debba sempre essere cancellato, piuttosto che i controller dovrebbero essere scritti per non avere uno stato condiviso, come i servlet Java. Passerai i valori al livello vista usando un meccanismo diverso (i locali, la richiesta, ecc.) Come in Java. I controllori servono solo per memorizzare lo stato specifico della richiesta * perché * sono istanziati per richiesta, tuttavia non è intrinseco al concetto di controller; altri quadri lo fanno diversamente. So che lo sai, solo chiarendo. –

+0

@DaveNewton Sì, ho considerato di entrare in questo, ma la domanda riguarda le prestazioni, quindi ho considerato che fosse coperto dal "qualcosa che deve reimpostare lo stato tra le richieste". Il jist è che, non c'è guadagno * performance * saggio mantenendo le istanze del controller in giro. Stai solo spostando l'allocazione/deallocazione in giro. – meagar

+0

Concordato, e preferisco di gran lunga istanza per richiesta: meno pensiero. –

Problemi correlati