Klingt ziemlich einfach, ich weiß, aber ich habe kürzlich von einem Kollegen erfahren, dass eine aufgerufene Methode startHttpServer
zu kompliziert ist, um sie zu verstehen, da sie den Server nur startet, wenn sie noch nicht ausgeführt wird. Ich stelle fest, dass ich Probleme bekomme, wenn ich antworte: "Ernsthaft? Ich mache das seit Jahrzehnten - es ist ein übliches Muster in der Programmierung." Öfter als ich zugeben möchte, kommt er mit einigen dokumentierten Beweisen zurück, die zeigen, dass die gesamte Programmier-Community hinter seiner Sichtweise steckt und ich mich am Ende verlegen fühle.
Frage : Gibt es ein dokumentiertes Entwurfsmuster hinter dem Konzept einer Methode, die keine Operation ist, wenn die erforderliche Aktion bereits wirksam ist? Oder, wenn kein Muster, hat es auch einen Namen? Und wenn nicht, gibt es einen Grund zu der Annahme, dass es zu kompliziert ist, eine Methode auf diese Weise zu schreiben?
quelle
startHttpServer
), und ja, hier gilt der Begriff "idempotent" Gut.Antworten:
Wie NickWilliams bereits sagte : Das Konzept, das das OP beschreibt, heißt idempotent (Nomen Idempotency ). Dies ist in der Tat eine gängige Praxis, insbesondere bei APIs auf hoher Ebene.
ABER: Benennen Sie die Funktion um.
Anstatt es zu
startHttpServer
nennenmakeSureHttpServerIsRunning
oderensureHttpServerIsRunning
.Wenn eine Funktion aufgerufen wird
startHttpServer
, erwarten die Leser, dass sie einen HTTP-Server startet. Wenn ich zehnmal hintereinander anrufe, werden zehn Server ausgeführt. Ihre Funktion macht das die meiste Zeit nicht. Außerdem lässt der Name mit "start" darauf schließen, dass ich, wenn nur ein Server ausgeführt werden soll, nachverfolgen muss, ob die Funktion bereits aufgerufen wurde oder nicht.Wenn eine Funktion aufgerufen wird
makeSureHttpServerIsRunning
, wird sie vermutlich die erforderlichen Schritte ausführen, um sicherzustellen, dass ein HTTP-Server ausgeführt wird. Dies geschieht höchstwahrscheinlich, indem überprüft wird, ob er bereits ausgeführt wird, und ansonsten gestartet wird. Ich gehe auch davon aus, dass die Funktion sicherstellt, dass der Server tatsächlich ausgeführt wird (das Starten eines Servers kann einige Zeit in Anspruch nehmen, in der er noch nicht vollständig ausgeführt wird).quelle
Benenne es um in
EnsureServerRunning
.Völlig eindeutig und es ist klar, dass es sicherstellt, dass es ausgeführt wird (falls nicht), ohne einen Neustart zu implizieren, falls dies der Fall ist.
(Alternativ
StartServerIfNotRunning
:?)quelle
Nicht wirklich ein Entwurfsmuster, aber ich würde Ihre Methode als idempotent bezeichnen . Dieser Begriff wird normalerweise für Remoteanrufe verwendet, aber die Beschreibung scheint dem zu entsprechen, was Sie tun.
Der serverseitige Effekt ist hier, dass der http-Server gestartet wird, sobald die Methode aufgerufen wird. Ich sehe nichts falsches an einer Methode, die dies tut.
Wenn Sie ein Entwurfsmuster benötigen, können Sie Ihren httpServer als Singleton verfügbar machen, der beim Initialisieren gestartet wird.
quelle
Als derjenige, der dieses Tool implementiert ,
startHttpServer
sollten Sie versuchen, es so einfach, reibungslos und nahtlos wie möglich zu gestalten ...Die Logik der Funktion
Technisch gesehen , durch die Spaltung von
startHttpServer
‚s - Logik in 2 Funktionen und nannte sie separat , alle , was Sie tun , ist bewegendstartHttpServer
‘ s Idempotenz in den Code stattdessen beide Funktionen aufrufen ... Außerdem , wenn Sie sowohl die Logik in eine dritte Funktion wickeln (was tutstartHttpServer
Dies zwingt Sie dazu, nicht getrockneten Code zu schreiben und ihn exponentiell überall dort zu duplizieren, wo Sie ihn aufrufen müsstenstartHttpServer
. Kurz gesagt,startHttpServer
muss sich dieisHttpServerRunning
Funktion nennen.Mein Punkt ist also:
isHttpServerRunning
Funktion implementieren , da diese möglicherweise ohnehin eigenständig benötigt wird ...startHttpServer
esisHttpServerRunning
, um seine nächste Aktion entsprechend zu definieren ...Sie können
startHttpServer
jedoch jeden Wert zurückgeben, den der Benutzer dieser Funktion benötigt, z. B .:0
=> Fehler beim Starten des Servers1
=> Server startet erfolgreich2
=> Server wurde bereits gestartetDie Benennung der Funktion
Was ist zuallererst das Hauptziel des Benutzers? So starten Sie den HTTP-Server , richtig?
Grundsätzlich ist es kein Problem, etwas zu starten, das bereits gestartet wurde, AKA
1*1=1
. Zumindest für michensureHttpServerIsRunning
scheint " " die Bezeichnung " " nicht kritisch erforderlich zu sein. Es interessiert mich mehr, wie lang, natürlich und einprägsam der Name der Funktion ist.Wenn Sie nun wissen möchten, wie die Funktion unter der Haube im Detail funktioniert, gibt es die Dokumentation oder die Codequelle dafür. Ich meine, wie für jede andere Funktion aus Bibliothek / Framework / API / etc ...
Sie lernen die Funktion einmal, während Sie sie mehrmals schreiben ...
Ich würde mich auf jeden Fall daran halten,
startHttpServer
was kürzer, einfacher und eindeutiger ist alsensureHttpServerIsRunning
.quelle
Ich nehme an, dass Ihr Kollege gemeint hat, dass
startHttpServer
das zu viel tut:Das sind zwei nicht zusammenhängende Teile des Codes. Eine ähnliche Situation besteht beispielsweise, wenn eine Desktop-Anwendung sicherstellen soll, dass sie beim Start nicht bereits ausgeführt wird. Es wird einen Teil des Codes geben, der App-Instanzen behandelt (zum Beispiel unter Verwendung eines Mutex), und den Code, der die Anwendungsnachrichtenschleife startet.
Dies bedeutet, dass Sie nicht eine, sondern mindestens zwei Methoden haben müssen :
isHttpServerRunning: boolean
startHttpServer
Der Anwendungseinstiegspunkt ruft die erste Methode und die zweite auf, wenn der Rückgabewert lautet
false
. Jetzt macht jede Methode eins und eins und ist leicht zu verstehen.¹ Wenn die Logik, die benötigt wird, um zu wissen, ob der Server bereits ausgeführt wird, zu komplex ist, ist möglicherweise eine weitere Aufteilung in mehrere Methoden erforderlich.
quelle
startHttpServer
mehr als eine Stelle im Code aufgerufen wird? Sollen überall mehrere ähnliche Zeilen eingefügt werden? Sollte dies mit allen Funktionen erfolgen? Bald wird Ihr Programm unendlich groß sein.startHttpServer
Methode ungefähr so aussehen wirdif (isHttpServerRunning()){ return; }
. Sie behaupten eine Geschäftsregel, dass "es nicht gültig ist, den HTTP-Server zu starten, wenn er bereits ausgeführt wird", aber dass dann die Verantwortung für die Durchsetzung dieser Regel bei einer anderen Person liegt. Ad-hoc und immer wieder an jedem Ort, an dem sie anrufen könntenstartHttpServer
.Da Sie keine Sprache angeben, haben in JavaScript viele Bibliotheken eine "einmalige" Funktion, z . B. Unterstrich . Wenn Ihnen das bekannt ist, bezeichnen Sie es als "einmaliges" Muster und benennen Sie Ihre Methode möglicherweise um.
Ich selbst komme eher aus Java und denke an die Begriffe "Caching" oder "Lazy Evaluation". "Idempotent" ist technisch korrekt und eine gute Wahl. wenn Sie einen funktionaleren Hintergrund haben.
quelle
restartHttpServer()
Methode vorstellen . Aber halt einfach an - was ist der Anwendungsfall dort? Sie mögen sporadische Verbindungsfehler? :-)ensureRunning()
? :-) Was den Administrator angeht, wäre es unglaublich ärgerlich und falsch, wenn dieser andere Code ständig neu gestartet würde, während der Administrator versucht, etwas zu ändern oder zu reparieren. Lassen Sie den Administrator neu starten, nicht den Code.Ich würde es vorziehen
startHttpServerIfNotIsRunning
.Auf diese Weise wird die Bedingung bereits im Methodennamen deutlich erwähnt.
Ensure
odermakeSure
scheint mir ein bisschen vage, da es kein technischer Ausdruck ist. Es hört sich so an, als ob wir nicht genau wissen, was passieren wird.quelle
Ensure
bedeutet. Ich mag dieses Wort für einen technischen Ausdruck immer noch nicht.Ensure
ist etwas menschliches. Ein System kann nichts sicherstellen, es wird nur das tun, was es tun soll.Was Ihr Kollege Ihnen hätte sagen sollen, ist, dass Sie kein Geschäft damit haben, diese Methode zu schreiben. Es wurde bereits viele Male geschrieben und ist besser, als Sie es wahrscheinlich schreiben werden. Beispiel: http://docs.ansible.com/ansible/latest/systemd_module.html https://docs.saltstack.com/de/latest/ref/states/all/salt.states.service.html
Aus architektonischer Sicht ist die Verwaltung eines Webservers mit einem willkürlichen Code ein wahrer Albtraum. Es sei denn, das Verwalten von Diensten ist ausschließlich die Aufgabe Ihres Codes. Aber ich vermute, Sie haben keine Monit (oder Kubernetes oder ...) geschrieben.
quelle
startServer
Funktion oder ähnliches zu haben, ist alles andere als ungewöhnlich . Das heißt nicht, dass Sie die kleinsten Details schreiben werden.