Angenommen, ich habe ein Codesegment, um eine Verbindung zum Internet herzustellen und die entsprechenden Verbindungsergebnisse anzuzeigen:
HttpRequest* httpRequest=new HttpRequest();
httpRequest->setUrl("(some domain .com)");
httpRequest->setRequestType(HttpRequest::Type::POST);
httpRequest->setRequestData("(something like name=?&age=30&...)");
httpRequest->setResponseCallback([=](HttpClient* client, HttpResponse* response){
string responseString=response->getResponseDataString();
if(response->getErrorCode()!=200){
if(response->getErrorCode()==404){
Alert* alert=new Alert();
alert->setFontSize(30);
alert->setFontColor(255,255,255);
alert->setPosition(Screen.MIDDLE);
alert->show("Connection Error","Not Found");
}else if((some other different cases)){
(some other alert)
}else
Alert* alert=new Alert();
alert->setFontSize(30);
alert->setPosition(Screen.MIDDLE);
alert->setFontColor(255,255,255);
alert->show("Connection Error","unknown error");
}
}else{
(other handle methods depend on different URL)
}
}
Der Code ist lang und wird häufig verwendet. Für den obigen Code sind jedoch keine zusätzlichen Dinge wie benutzerdefinierte Funktion und Klasse erforderlich (HttpRequest und Alert werden beide standardmäßig vom Framework bereitgestellt). Obwohl das Codesegment lang ist, ist dies der Fall unkompliziert und nicht komplex (es ist lang, nur weil es Bündel von Einstellungen wie URL, Schriftgröße ... gibt), und das Codesegment weist geringe Unterschiede zwischen Klassen auf (z. B. URL, Anforderungsdaten, Fehlercode-Handle-Fälle, normales Handle) Fälle...)
Meine Frage ist, ist es akzeptabel, langen, aber unkomplizierten Code zu kopieren und einzufügen, anstatt sie in eine Funktion zu packen, um die Abhängigkeit von Code zu verringern?
Alert
Objekte?) Stellen Sie sich nun vor, Sie müssen jede kopierte Instanz dieses Codes finden, um den Fehler zu beheben. Stellen Sie sich nun vor, nicht Sie müssen es tun, sondern ein verrückter Axtmörder, der weiß, dass Sie derjenige waren, der all diese Kopien überhaupt erstellt hat.Antworten:
Sie müssen die Kosten der Änderung berücksichtigen. Was wäre, wenn Sie die Art und Weise, wie Verbindungen hergestellt werden, ändern möchten? Wie einfach wäre es? Wenn Sie viel duplizierten Code haben, kann es sehr zeitaufwändig und fehleranfällig sein, alle Stellen zu finden, die geändert werden müssen.
Sie müssen auch Klarheit berücksichtigen. Das Betrachten von 30 Codezeilen ist höchstwahrscheinlich nicht so einfach zu verstehen wie ein einzelner Aufruf einer "connectToInternet" -Funktion. Wie viel Zeit wird beim Versuch, den Code zu verstehen, verloren gehen, wenn neue Funktionen hinzugefügt werden müssen?
In bestimmten seltenen Fällen ist die Vervielfältigung kein Problem. Zum Beispiel, wenn Sie ein Experiment durchführen und der Code am Ende des Tages weggeworfen wird. Im Allgemeinen überwiegen die Kosten für die Vervielfältigung die geringe Zeitersparnis, wenn der Code nicht in eine separate Funktion gezogen werden muss .
Siehe auch https://softwareengineering.stackexchange.com/a/103235/63172
quelle
HttpRequest
alle gleich sind ", ist ein leicht zu beweisender Irrtum.Nein.
Tatsächlich sollte sogar Ihr "einfacher" Code in kleinere Teile aufgeteilt werden. Mindestens zwei.
Eine, die die Verbindung herstellt und die normale Antwort von 200 verarbeitet. Was passiert zum Beispiel, wenn Sie in einigen Fällen von einem POST zu einem PUT wechseln? Was ist, wenn Sie zig Millionen dieser Verbindungen herstellen und Multithreading oder Verbindungspooling benötigen? Wenn Sie den Code mit einem Argument für die Methode an einer einzigen Stelle haben, wird dies viel einfacher
Ebenso eine andere, um Fehler zu behandeln. Zum Beispiel, wenn Sie die Farbe oder die Schriftgröße der Warnung ändern. Oder Sie haben Probleme mit zeitweiligen Verbindungen und möchten die Fehler protokollieren.
quelle
Nein.
Für mich ist das entscheidende Argument dieses:
Wenn Sie ein Stück Code in verwenden mehr als ein Ort , dann, wenn sie sich ändert, müssen Sie ändern es in mehr als einem Ort oder starten Sie Unstimmigkeiten zu bekommen - „seltsame Dinge“ zu passieren beginnen (dh Sie einführen Bugs).
Und so sollte es umso einfacher sein, eine Funktion umzugestalten.
Und was tun Nutzer lieben zu ändern? Schriftarten, Schriftgrößen, Farben usw. usw.
Jetzt; An wie vielen Stellen müssen Sie denselben Code ändern, um sie alle wieder in derselben Farbe / Schriftart / Größe zu erhalten? (Empfohlene Antwort: nur ein ).
Variation => Funktionsparameter.
quelle
Das hat eigentlich nichts mit Kopieren und Einfügen zu tun. Wenn Sie Code von einer anderen Stelle übernehmen, liegt es in der Sekunde, in der Sie den Code übernehmen, an Ihrem Code und Ihrer Verantwortung. Es spielt also keine Rolle, ob der Code vollständig von Ihnen selbst kopiert oder geschrieben wurde.
In Ihren Warnungen treffen Sie einige Entwurfsentscheidungen. Höchstwahrscheinlich sollten für alle Warnungen ähnliche Entwurfsentscheidungen getroffen werden. Es ist also wahrscheinlich, dass Sie eine Methode irgendwo "ShowAlertInAStyleSuitableForMyApplication" oder etwas kürzer haben sollten, und diese sollte aufgerufen werden.
Sie werden viele http-Anfragen mit ähnlicher Fehlerbehandlung haben. Sie sollten die Fehlerbehandlung wahrscheinlich nicht immer wieder duplizieren, sondern die allgemeine Fehlerbehandlung extrahieren. Vor allem, wenn Ihre Fehlerbehandlung etwas komplizierter wird (was ist mit Timeout-Fehlern, 401 usw.).
quelle
Die Vervielfältigung ist unter bestimmten Umständen in Ordnung. Aber nicht in diesem. Diese Methode ist zu komplex. Es gibt eine Untergrenze, bei der das Duplizieren einfacher ist als das "Ausklammern" einer Methode.
Beispielsweise:
ist doof, mach einfach a + b.
Aber wenn Sie nur ein kleines bisschen komplexer werden, sind Sie normalerweise weit davon entfernt.
soll werden
In Ihrem Fall sehe ich vier "Methoden". Wahrscheinlich in verschiedenen Klassen. Eine, um die Anfrage zu stellen, eine, um die Antwort zu erhalten, eine, um Fehler anzuzeigen, und eine Art Rückruf, der aufgerufen wird, nachdem die Antwort zurückgekehrt ist, um die Antwort zu verarbeiten. Ich persönlich würde wahrscheinlich noch eine Art "Wrapper" hinzufügen, um die Anrufe zu vereinfachen.
Um eine Webanfrage zu stellen, möchte ich, dass ein Anruf ungefähr so aussieht:
Diese Zeile würde ich überall in meinem Code haben. Wenn ich dann Änderungen an der Art und Weise vornehmen musste, wie ich Dinge bekomme, konnte ich dies schnell und mit viel weniger Aufwand tun.
Dies hält auch den Code trocken und hilft bei der SRP .
quelle
In einem Projekt beliebiger Größe / Komplexität möchte ich in der Lage sein, Code zu finden, wenn ich ihn für die folgenden Zwecke benötige:
Wäre es nicht schön, sich einem laufenden Projekt anzuschließen oder mehrere Jahre an einem Projekt weiterzuarbeiten, und wenn eine neue Anfrage nach "Verbindung zum Internet herstellen und Verbindungsergebnisse anzeigen" an einem leicht zu findenden Ort aufgrund eines Gutes Design anstatt sich darauf zu verlassen, den gesamten Code nach einer http-Anfrage zu durchsuchen? Mit Google ist es wahrscheinlich ohnehin einfacher zu finden.
Keine Sorge, ich bin der Neue, und ich werde diesen Codeblock überarbeiten, weil ich so verärgert bin, dass ich mich diesem ahnungslosen Team mit der schrecklichen Codebasis angeschlossen habe, oder weil ich jetzt wie der Rest von unter großem Druck stehe Sie und werden es einfach kopieren und einfügen. Zumindest wird es den Chef von meinem Rücken abhalten. Wenn das Projekt wirklich als Katastrophe eingestuft wird, empfehle ich als Erster, es neu zu schreiben, indem Sie die Version in dem neuesten und besten Rahmen kopieren und einfügen, den keiner von uns versteht.
quelle
Eine Klasse und / oder eine Funktion ist meiner Meinung nach besser. Ausnahmsweise wird die Datei dadurch kleiner, was ein großer Vorteil ist, wenn Sie mit Webanwendungen oder Anwendungen für Geräte mit wenig Speicher (IoT, ältere Telefone usw.) arbeiten.
Und natürlich ist der beste Punkt, dass Sie, wenn Sie aufgrund neuer Protokolle usw. etwas zu ändern haben, nur den Inhalt der Funktion ändern und diese Funktion nicht unzählige Male irgendwo ablegen, was sie möglicherweise sogar in verschiedenen Dateien noch schwieriger macht finden und ändern.
Ich habe einen ganzen SQL-Interpreter geschrieben, damit ich in PHP besser von MySQL auf MySQLi umsteigen kann , weil ich nur meinen Interpreter ändern muss und alles funktioniert, obwohl das ein extremes Beispiel ist.
quelle
Um zu entscheiden, ob ein Code dupliziert oder in eine Funktion verschoben werden soll, die zweimal aufgerufen wird, versuchen Sie, die wahrscheinlichere zu ermitteln:
Es ist notwendig, beide Verwendungen des Codes auf dieselbe Weise zu ändern.
Es ist erforderlich, mindestens eine Verwendung des Codes zu ändern, damit sie sich unterscheiden.
Im ersten Fall ist es wahrscheinlich besser, wenn eine Funktion beide Verwendungen verarbeitet. Im letzteren Fall ist es wahrscheinlich besser, einen separaten Code für die beiden Verwendungen zu haben.
Wenn Sie entscheiden, ob ein Code, der einmal verwendet wird, in eine andere Funktion geschrieben oder aus dieser herausgezogen werden soll, müssen Sie herausfinden, wie das erforderliche Verhalten der Funktion vollständig beschrieben wird. Wenn eine vollständige und genaue Beschreibung des für die Funktion erforderlichen Verhaltens genauso lang oder länger als der Code selbst ist, kann das Verschieben des Codes in eine separate Funktion das Verständnis der Dinge eher erschweren als erleichtern. Es kann sich dennoch lohnen, dies zu tun, wenn die Wahrscheinlichkeit groß ist, dass ein zweiter Anrufer dieselbe Funktion verwenden muss und künftige Änderungen an der Funktion beide Anrufer betreffen müssen. Wenn dies jedoch nicht berücksichtigt wird, würde die Lesbarkeit die Aufteilung der Elemente begünstigen auf die Ebene, auf der der Code und eine Beschreibung seines erforderlichen Verhaltens ungefähr gleich lang wären.
quelle