Wenn ich versuche, eine neue Methode zu erstellen, um B anders zu behandeln, wird sie zur Codeduplizierung aufgerufen.
Nicht alle Codeduplikationen sind gleich.
Angenommen, Sie haben eine Methode, die zwei Parameter verwendet, die aufgerufen werden total()
. Angenommen, Sie haben einen anderen angerufen add()
. Ihre Implementierungen sehen völlig identisch aus. Sollten sie zu einer Methode zusammengeführt werden? NEIN!!!
Beim Don't-Repeat-Yourself- oder DRY-Prinzip geht es nicht darum, Code zu wiederholen. Es geht darum, eine Entscheidung, eine Idee, zu verbreiten, damit Sie, wenn Sie Ihre Idee jemals ändern, sie überall neu schreiben müssen, wo Sie diese Idee verbreiten. Blegh. Das ist schrecklich. Tu es nicht. Verwenden Sie stattdessen DRY, um Entscheidungen an einem Ort zu treffen .
Das DRY-Prinzip (Wiederholen Sie sich nicht) besagt:
Jedes Wissen muss eine einzige, eindeutige und maßgebliche Darstellung innerhalb eines Systems haben.
wiki.c2.com - Wiederholen Sie sich nicht
DRY kann jedoch zur Gewohnheit werden, Code nach einer ähnlichen Implementierung zu durchsuchen, die wie das Kopieren und Einfügen von einem anderen Ort aussieht. Dies ist die hirntote Form von DRY. Zum Teufel, Sie könnten dies mit einem statischen Analysewerkzeug tun. Es hilft nicht, weil es den Punkt von DRY ignoriert, der darin besteht, den Code flexibel zu halten.
Wenn sich meine Gesamtanforderungen ändern, muss ich möglicherweise meine total
Implementierung ändern . Das bedeutet nicht, dass ich meine add
Implementierung ändern muss . Wenn ein Goober sie zu einer Methode zusammengefügt hat, habe ich jetzt ein bisschen unnötigen Schmerz.
Wie viel Schmerz? Sicherlich könnte ich den Code einfach kopieren und eine neue Methode erstellen, wenn ich sie brauche. Also keine große Sache, oder? Malarky! Wenn nichts anderes kostet dich mich einen guten Namen! Gute Namen sind schwer zu finden und reagieren nicht gut, wenn Sie an ihrer Bedeutung herumspielen. Gute Namen, die die Absicht klar machen, sind wichtiger als das Risiko, dass Sie einen Fehler kopiert haben, der offen gesagt leichter zu beheben ist, wenn Ihre Methode den richtigen Namen hat.
Mein Rat ist also, aufhören zu lassen, dass Knie-Ruck-Reaktionen auf ähnlichen Code Ihre Codebasis in Knoten binden. Ich sage nicht, dass Sie die Tatsache, dass Methoden existieren, ignorieren und stattdessen wohl oder übel kopieren und einfügen können. Nein, jede Methode sollte einen verdammt guten Namen haben, der die eine Idee unterstützt, um die es geht. Wenn die Implementierung mit der Implementierung einer anderen guten Idee übereinstimmt, wen interessiert das heute?
Auf der anderen Seite, wenn Sie eine sum()
Methode haben, die eine identische oder sogar andere Implementierung hat als total()
Ihre, aber immer wenn sich Ihre Gesamtanforderungen ändern, müssen Sie diese ändern, sum()
dann besteht eine gute Chance, dass dies dieselbe Idee unter zwei verschiedenen Namen ist. Der Code wäre nicht nur flexibler, wenn er zusammengeführt würde, es wäre auch weniger verwirrend, ihn zu verwenden.
Was boolesche Parameter betrifft, ja, das ist ein übler Codegeruch. Dieses Kontrollflussmaterial ist nicht nur ein Problem, es zeigt auch, dass Sie eine Abstraktion an einem schlechten Punkt eingeschnitten haben. Abstraktionen sollen die Verwendung einfacher und nicht komplizierter machen. Das Übergeben von Bools an eine Methode zur Steuerung ihres Verhaltens ist wie das Erstellen einer geheimen Sprache, die entscheidet, welche Methode Sie wirklich aufrufen. Au! Tu mir das nicht an. Geben Sie jeder Methode ihren eigenen Namen, es sei denn, Sie haben einen ehrlichen Polymorphismus .
Jetzt scheinen Sie von der Abstraktion ausgebrannt zu sein. Das ist schade, denn Abstraktion ist eine wunderbare Sache, wenn sie gut gemacht wird. Sie benutzen es oft, ohne darüber nachzudenken. Jedes Mal, wenn Sie ein Auto fahren, ohne das Zahnstangensystem verstehen zu müssen, jedes Mal, wenn Sie einen Druckbefehl verwenden, ohne an Betriebssystemunterbrechungen zu denken, und jedes Mal, wenn Sie Ihre Zähne putzen, ohne an jede einzelne Borste zu denken.
Nein, das Problem, mit dem Sie anscheinend konfrontiert sind, ist eine schlechte Abstraktion. Abstraktion, die geschaffen wurde, um einem anderen Zweck als Ihren Bedürfnissen zu dienen. Sie benötigen einfache Schnittstellen zu komplexen Objekten, mit denen Sie die Erfüllung Ihrer Anforderungen anfordern können, ohne diese Objekte jemals verstehen zu müssen.
Wenn Sie Client-Code schreiben, der ein anderes Objekt verwendet, wissen Sie, welche Anforderungen Sie haben und was Sie von diesem Objekt benötigen. Das tut es nicht. Aus diesem Grund besitzt Client-Code die Schnittstelle. Wenn Sie der Kunde sind, kann Ihnen nichts sagen, was Sie brauchen, außer Sie. Sie stellen eine Schnittstelle zur Verfügung, die Ihre Anforderungen zeigt, und fordern, dass alles, was Ihnen übergeben wird, diese Anforderungen erfüllt.
Das ist Abstraktion. Als Kunde weiß ich nicht einmal, womit ich spreche. Ich weiß nur, was ich davon brauche. Wenn das bedeutet, dass Sie etwas einpacken müssen, um die Benutzeroberfläche zu ändern, bevor Sie es mir übergeben. Es ist mir egal. Tu einfach was ich tun muss. Hör auf, es kompliziert zu machen.
Wenn ich in eine Abstraktion schauen muss, um zu verstehen, wie man sie verwendet, ist die Abstraktion fehlgeschlagen. Ich sollte nicht wissen müssen, wie es funktioniert. Nur dass es funktioniert. Gib ihm einen guten Namen und wenn ich hineinschaue, sollte mich das, was ich finde, nicht überraschen. Lassen Sie mich nicht weiter nach innen schauen, um mich daran zu erinnern, wie man es benutzt.
Wenn Sie darauf bestehen, dass die Abstraktion auf diese Weise funktioniert, spielt die Anzahl der dahinter stehenden Ebenen keine Rolle. Solange Sie nicht hinter die Abstraktion schauen. Sie bestehen darauf, dass die Abstraktion Ihren Bedürfnissen entspricht und sich nicht an ihre anpasst. Damit dies funktioniert, muss es einfach zu bedienen sein, einen guten Namen haben und nicht auslaufen .
Das ist die Einstellung, die Dependency Injection hervorgebracht hat (oder nur Referenzübergabe, wenn Sie wie ich in der alten Schule sind). Es funktioniert gut, wenn Komposition und Delegierung der Vererbung vorgezogen werden . Die Einstellung hat viele Namen. Mein Favorit ist erzählen, nicht fragen .
Ich könnte dich den ganzen Tag in Prinzipien ertränken. Und es hört sich so an, als ob Ihre Mitarbeiter es bereits sind. Aber hier ist die Sache: Im Gegensatz zu anderen technischen Bereichen ist diese Software-Sache weniger als 100 Jahre alt. Wir alle finden es immer noch heraus. Lassen Sie sich also nicht von jemandem mit viel einschüchterndem Hörbuch dazu zwingen, schwer lesbaren Code zu schreiben. Hören Sie ihnen zu, aber bestehen Sie darauf, dass sie Sinn ergeben. Nimm nichts vom Glauben. Leute, die auf irgendeine Weise codieren, nur weil ihnen gesagt wurde, dass dies der Weg ist, ohne zu wissen, warum sie die größten Probleme von allen machen.