Beispiel
Ich bin auf monolithischen Code gestoßen, der "alles" an einem Ort erledigt - Daten aus der Datenbank laden, HTML-Markup anzeigen und als Router / Controller / Aktion fungieren. Ich begann SRP anzuwenden, um Datenbankcode in eine eigene Datei zu verschieben, um bessere Namen für die Dinge zu erhalten, und alles sah gut aus, aber dann begann ich Zweifel zu haben, warum ich das tue.
Warum umgestalten? Was ist der Zweck? Ist es nutzlos Was ist der vorteil Beachten Sie, dass ich die monolithische Datei größtenteils so belassen habe, wie sie ist, aber nur den kleineren Teil überarbeitet habe, der für den Bereich relevant war, in dem ich etwas arbeiten musste.
Originalcode:
Um ein konkretes Beispiel zu geben, bin ich auf dieses Code-Snippet gestoßen - es lädt Produktspezifikationen entweder über eine bekannte Produkt-ID oder über eine vom Benutzer ausgewählte Versions-ID:
if ($verid)
$sql1 = "SELECT * FROM product_spec WHERE id = " . clean_input($verid);
else
$sql1 = "SELECT * FROM product_spec WHERE product_id = " . clean_input($productid) ;
$result1 = query($sql1);
$row1 = fetch_array($result1);
/* html markup follows */
Refactoring:
Da ich einige Arbeiten erledige, bei denen ich Änderungen an diesem bestimmten Teil des Codes vornehmen muss, habe ich das Repository-Muster geändert und es aktualisiert, um objektorientierte MySQL-Funktionen zu verwenden:
//some implementation details omitted
$this->repository = new SpecRepository($mysql);
if ($verid)
$row1 = $this->repository->getSpecByVersion($verid);
else
$row1 = $this->repository->getSpecByProductId($productid);
/* html markup follows to be refactored or left alone till another time*/
//added new class:
class SpecRepository extends MySqlRepository
{
function getSpecByVersion(int $verid)
{
return $this->getMySql()->paramQuery("
SELECT * FROM product_spec WHERE id = ?
", $verid)->getSingleArray();
}
function getSpecByProductId(int $productid)
{
return $this->getMySql()->paramQuery("
SELECT * FROM product_spec WHERE product_id = ?
", $productid)->getSingleArray();
}
}
Soll ich das machen
Rückblickend auf die Änderungen ist der Code immer noch vorhanden, Code mit derselben Funktionalität, aber in unterschiedlichen Dateien, unterschiedlichen Namen und Orten, wobei eher ein objektorientierter Stil als ein prozeduraler verwendet wird. Eigentlich ist es lustig zu bemerken, dass der überarbeitete Code trotz der gleichen Funktionalität viel aufgeblähter aussieht.
Ich sehe einige Antworten mit den Worten "Wenn Sie nicht wissen, warum Sie umgestalten, tun Sie es nicht", und vielleicht stimme ich Ihnen zu. Meine Gründe sind, die Qualität des Codes im Laufe der Zeit zu verbessern (und ich hoffe, dass ich dies tun werde, indem ich SRP und andere Prinzipien befolge).
Sind das gute Gründe oder verschwende ich meine Zeit damit, Code auf diese Weise neu zu ordnen? Um ehrlich zu sein, fühlt sich das Umgestalten insgesamt ein bisschen wie das Treten von Wasser an - es braucht Zeit und wird in Bezug auf SRP "getrennter", aber trotz meiner guten Absichten habe ich nicht das Gefühl, dass ich erstaunliche Verbesserungen mache. Daher wird überlegt, ob es am besten ist, den Code wie zuvor zu belassen und nicht umzugestalten.
Warum habe ich überhaupt umgestaltet?
In meinem Fall füge ich einer neuen Produktlinie neue Funktionen hinzu, sodass ich entweder der vorhandenen Codestruktur für ähnliche Produktlinien folgen oder meine eigene schreiben muss.
Select * from ..
ein Anti-Muster betrachtet werden kann. Siehe stackoverflow.com/q/3639861/31326select *
wird dies zu einer "Best Practice".Antworten:
In dem konkreten Beispiel, das Sie angegeben haben, war ein Refactoring möglicherweise nicht erforderlich, zumindest noch nicht. Aber Sie haben gesehen, dass es in Zukunft ein Potenzial für chaotischeren Code gibt, der zu einem längeren und langwierigeren Refactoring geführt hätte. Sie haben also die Initiative ergriffen und die Dinge jetzt aufgeräumt.
Ich würde auch sagen, dass der Vorteil, den Sie hier gewonnen haben, Code ist, der zumindest aus meiner Sicht einfacher zu verstehen ist, als jemand, der Ihre Codebasis nicht kennt.
Allgemein:
Erleichtert das Refactoring anderen Entwicklern das Verständnis Ihres Codes?
Erleichtert das Refactoring die Verbesserung des Codes?
Erleichtert das Refactoring die Pflege des Codes?
Erleichtert das Refactoring das Debuggen?
Wenn die Antwort auf eine dieser Fragen "Ja" war, dann war es das wert und es war mehr als nur "Code bewegen"?
Wenn die Antwort auf alle diese Fragen "Nein" war, musste sie möglicherweise nicht überarbeitet werden.
Die endgültige Größe der Codebasis könnte in Bezug auf die LoC größer sein (obwohl einige Refactorings die Codebasis durch Straffung von redundantem Code verkleinern können), aber das sollte kein Faktor sein, wenn es andere Vorteile gibt.
quelle
Refactoring bläht sich auf, wenn Sie einen Monolithen zerlegen.
Sie haben den Vorteil jedoch bereits gefunden.
"In meinem Fall füge ich einer neuen Produktlinie neue Funktionen hinzu."
Sie können einem Monolithen nicht ohne weiteres Funktionen hinzufügen, ohne Dinge zu beschädigen.
Sie sagten, dass derselbe Code die Daten abruft und das Markup ausführt. Großartig, bis Sie ändern möchten, welche Spalten Sie auswählen und bearbeiten, um sie unter bestimmten Bedingungen anzuzeigen. Plötzlich funktioniert Ihr Markup-Code in einem bestimmten Fall nicht mehr und Sie müssen umgestalten.
quelle
if/else
Block hinzufügen und dem ursprünglichen Codestil folgen, um SQL-Anweisungen hinzuzufügen, und dann ein neues HTML-Markup in dieselbe Monolithdatei einfügen. Und um die Spalten zu ändern, würde ich den if / else-Block finden, der für die Unterbringung von SQL-Zeilen verantwortlich ist, und diese SQL bearbeiten, um Änderungen an den Spalten vorzunehmen, ohne diese Datei aufzulösen.Ich überlege mir eine Umgestaltung, wenn ich weiß, dass ich Monate oder sogar Jahre mit diesem Projekt arbeiten muss. Wenn ich hier und da eine Änderung vornehmen muss, dann widersetze ich mich dem Drang, Code zu verschieben.
Die bevorzugte Methode zum Refactoring ist, wenn ich einen Basiscode mit einer Art automatisierten Tests habe. Trotzdem muss ich sehr vorsichtig sein, was ich ändere, um sicherzustellen, dass die Dinge wie zuvor funktionieren. Sie werden sehr bald das Vertrauen verlieren, wenn Sie Fehler in anderen Bereichen als dem, in dem Sie arbeiten sollten, melden.
Ich schätze Refactoring aus folgenden Gründen:
comment
den Code über Variablennamen, Methodennamenarchitect
die Lösung aufwenden. Dies wird beim Schreiben passieren - den Code hin und her schreiben.In einer perfekten Welt sollten Refactorings durch Unit-Tests, Integrationstests usw. verifiziert werden. Wenn es keine gibt, füge sie hinzu. Auch einige IDE könnte viel helfen. Normalerweise benutze ich ein Plugin, das Geld kostet. Ich möchte wenig Zeit mit Refactorings verbringen und dabei sehr effizient sein.
Ich habe auch Bugs eingeführt. Ich kann sehen, warum einige QA fragen
are you guys doing refactoring? because everything stopped working!
Dies ist das Risiko, das das Team eingehen muss, und wir müssen immer transparent darüber sein.Im Laufe der Jahre stellte ich fest, dass kontinuierliches Refactoring meine Produktivität verbesserte. Es war viel einfacher, neue Funktionen hinzuzufügen. Auch große Umbauten erforderten kein vollständiges Umschreiben, wie dies häufig der Fall war, wenn die Codebasis nicht an die Produktentwicklung angepasst wurde. Es macht auch Spaß.
quelle
I
mitto
though.Ich denke, die Frage, die Sie sich stellen müssen, ist nicht so sehr "Gibt es einen Nutzen?" aber "Wer wird für diese Arbeit bezahlen?"
Wir können uns alle über die wahrgenommenen Vorteile bis zum Ende der Tage streiten, aber wenn Sie keinen Kunden haben, der an diese Vorteile glaubt und sie genug schätzt, um für die Änderungen zu zahlen, sollten Sie sie nicht tun.
Es ist allzu einfach, wenn Sie irgendwo im Entwicklerteam sind, um Code zu sehen und ihn umzugestalten, um ihn "besser" zu machen. Es ist jedoch sehr schwierig, einen Wert auf "besseren Code" zu setzen, wenn das Produkt bereits funktioniert.
Dinge wie die "schnellere Entwicklung neuer Funktionen" schränken es nicht ein, weil sie nur die Kosten senken. Sie müssen Umsatz generieren.
quelle
Meiner Meinung nach ist Refactoring eine gute Investition.
Andernfalls erhalten Sie bald technische Schulden (ungelöste Probleme, fehlerhafter Code, der nur unter bestimmten Bedingungen funktioniert, usw.). Die technischen Schulden werden bald immer größer, bis die Software nicht mehr wartbar ist.
Damit das Refactoring funktioniert, müssen Sie jedoch auch in Tests investieren. Sie sollten automatisierte Tests erstellen. Idealerweise sollten Sie Komponententests und Integrationstests durchführen. Dies verhindert, dass Sie vorhandenen Code beschädigen.
Wenn Sie Ihren Chef oder Kollegen überzeugen müssen, sollten Sie einige Bücher über agile Methoden (zB SCRUM) und testgetriebene Entwicklung lesen.
quelle