2013-01-05 5 views
19

Von meinem vorherigen question habe ich verstanden, dass Rails eine Controller-Instanz für jede Anfrage erstellt.Warum erstellt Rails für jede Anforderung einen Controller?

Meine Frage ist, denn diese unterliegen der Gestaltung des Projekts arbeite ich an zusammenhängt:

Warum Rails eine neue Instanz von

class SomeController < ApplicationController; end 

jede eingehende Anfrage bearbeiten schafft? Warum nicht einfach Singleton-Objekte erstellen und Anfragen an diese weiterleiten? Dies scheint effizienter zu sein, da wir keine Ressourcen für die Zuweisung und Reinigung von Objekten für Anfragen verschwenden werden.

+1

Gute Frage, Sie sollten DHH dazu fragen :) Aber ich denke, der wichtigste Punkt ist, absolut eine Umgebung zu einer anderen zu isolieren. Denn sonst muss das System mehr Rechenleistung für die Verteilungslogik ausgeben. imho –

+3

Weil es einfacher ist, über Code nachzudenken, wenn kein Risiko besteht, auf die Daten einer anderen Anfrage zu stampfen. –

+0

Keine Überraschungen, aber es scheint, dass Grails das Gleiche tut. –

Antwort

32

Der Aufwand für die Instanziierung einer neuen Controllerinstanz ist unbedeutend und bedeutet, dass zwischen zwei völlig unabhängigen Anforderungen kein versehentlich freigegebener Status vorhanden ist. Jede "Einsparung" an Prozessorzeit würde durch das Potenzial, verheerende Bugs zu produzieren, mehr als ausgeglichen.

Denken Sie daran, dass die Controller zum Speichern des anforderungsspezifischen Status dienen. Die Wiederverwendung von Controllern würde erfordern, dass Sie alle @variable, die Sie jemals festgelegt haben, zu Beginn jeder Aktion zurücksetzen. Sonst könnte etwas wie @is_admin = true aufgezogen und nie gelöscht werden. Die weniger konstruierten Fehler, die Sie eigentlich einführen würden, wären viel subtiler und würden die Entwicklerzeit verkürzen.

Sie sehen Optimierungen, wo keine sind. Etwas muss den Status beibehalten und zwischen den Anforderungen zurücksetzen, oder Sie haben diesen Alptraum des versehentlich freigegebenen Status. Wenn Sie Controller-Instanzen zwischen Anforderungen persistieren, schieben Sie einfach den Job zum Verwalten/Zurücksetzen des Status auf eine niedrigere Stufe, wobei die Antwort immer noch ist, um eine neue Instanz einer staatsverwaltenden Klasse für jede Anforderung zu instanziieren. Computer sind sehr gut bei der Zuteilung und Freigabe von Ressourcen, so nie sich darum kümmern, bis Sie tatsächlich wissen, dass es ein Flaschenhals ist. In diesem Fall ist die Instanziierung eines neuen Controllers für jede Anforderung leicht die richtige Wahl.

Im Fall von Schienen, @variable = value verwenden zu können, ist ein großer Gewinn von einem Code-Übersichtlichkeit und Bedienbarkeit Stand-Punkt, und dies mehr oder weniger erfordert jede Instanz eines Controllers Verwerfen, wenn die Anforderung abgeschlossen ist.

+2

Nun ... es ist nicht so sehr, dass '@ foo' immer gelöscht werden müsste, sondern dass Controller geschrieben werden müssen, um keinen gemeinsamen Status zu haben, wie Java-Servlets. Sie würden Werte an die Ansichtsebene übergeben, indem Sie einen anderen Mechanismus verwenden (Locals, die Anforderung usw.), wie in Java. Controller dienen nur dazu, anforderungsspezifische Zustände zu speichern *, weil sie pro Anfrage instanziiert werden - dies ist jedoch nicht unbedingt das Konzept eines Controllers; andere Frameworks machen es anders. Ich weiß, dass Sie das wissen, nur klärend. –

+0

@DaveNewton Ja, ich habe darüber nachgedacht, in dieses Thema zu kommen, aber die Frage bezieht sich auf die Leistung, also dachte ich, dass es durch das "Etwas muss den Status zwischen den Anforderungen zurücksetzen" abgedeckt wird. Der Vorteil ist, dass es keine Leistungssteigerung gibt, indem Controller-Instanzen herumgehalten werden. Sie verschieben nur die Zuordnung/Freigabe. – meagar

+0

Einverstanden, und ich bevorzuge Instanz-pro-Anfrage: weniger zu denken. –

Verwandte Themen