Wie schreibe ich Code, der wiederverwendet wird?



Die Idee, dass für die Wiederverwendung entwickelter Code ein Allheilmittel für alle Programmierprobleme sein kann, ist ein gefährlicher Mythos. Jetzt erkläre ich warum.

Stellen wir uns vor, Sie schreiben eine Bibliothek und kommen plötzlich auf eine brillante Idee, aus der eine verallgemeinerte Lösung abgeleitet werden kann, die in einer Vielzahl von Fällen anwendbar ist. Sie verschreiben fieberhaft APIs, die jede Funktionalität überfordern und sich an jedes Szenario anpassen. Sie fügen alle Skripte hinzu, die Ihnen nur in den Sinn kommen. Der Code schwillt und schwillt an, aber letztendlich wird er im wahrsten Sinne des Wortes verallgemeinert. Er ist wie heiße Kuchen, und Sie sind glücklich.

Eines Tages zeichnet sich jedoch eine neue API ab. Es ist prägnanter und für eine größere Anzahl von Szenarien geeignet und gewinnt darüber hinaus an Geschwindigkeit und Einfachheit. Ihre API gerät in Vergessenheit - jeder wechselt sofort zu einer verlockenden Neuheit. Nach einiger Zeit wiederholt sich jedoch die gleiche Geschichte: Die API wird aufgrund ständiger Ergänzungen des Codes, der für neue Bedingungen entwickelt wurde, immer schwerer, bis am Ende etwas anderes dazu kommt, ihn zu ersetzen. Und so weiter bis ins Unendliche.

Warum ist das so?

Die Wurzel aller Probleme in diesem Fall ist der Wunsch, verallgemeinerte Lösungen zu schreiben. Wenn der reproduzierbare Code einen Standardfall als Standard verwendet, wird er aufgebläht, unbequem zu verwenden und verwandelt sich allmählich in reinen Kopfschmerz.

Ein gewisser Grad an Verallgemeinerung ist Voraussetzung für die wiederholte Verwendung von Code. Aber wenn Sie damit zu weit gehen, beginnt der Utilitarismus zu leiden. Wenn ich meine Gedanken auf den Punkt bringe, läuft das Schreiben von Code, der wiederverwendbar ist, nicht darauf hinaus, ihn so umfassend wie möglich zu gestalten. Alles ist viel komplizierter.
Um einen praktisch reproduzierbaren Code zu erstellen, müssen Sie sicherstellen, dass er nicht regelmäßig, sondern bei Bedarf spontan verwendet wird. Wenn Sie an einem Produkt arbeiten, stoßen Sie plötzlich auf einen Code, der für seine Anforderungen verwendet werden kann. Sie nehmen dieses Snippet, ändern es ein wenig und implementieren es in der Anwendung. Sie zahlen also nur für das, was wirklich von Nutzen ist und genau dann, wenn es nötig ist.

Später stellen Sie fest, dass diese überarbeitete Version in einer anderen Anwendung nützlich sein kann. Sie nehmen dieses Fragment erneut, modifizieren es leicht und verwenden es im dritten Kreis. Wenn Sie also die Reproduzierbarkeit schrittweise erhöhen, können Sie nicht nur den größtmöglichen Nutzen aus diesem Fragment ziehen, sondern Ihr Produkt auch vor Code schützen, der nichts dafür tut und in der Regel nicht benötigt wird.

Das Wichtigste dabei ist keineswegs, die Zukunft vorherzusagen. Die Reproduzierbarkeit sollte auf die aktuellen Sichtbarkeitsgrenzen beschränkt sein. In Zukunft werden Sie den Code entsprechend korrigieren, wenn sich eine neue Gelegenheit für seine Anwendung ergibt. Dies erspart Ihnen nicht nur Zeit und Mühe, sondern auch das Schreiben von sparsamerem, coolerem und modernerem Code, der für die Wiederverwendung geschärft wurde.

Hier finden Sie einige praktische Vorschläge, wie Sie Code wiederverwendbar machen können.

Vermeiden Sie Doppelarbeit


Wie Lemony Sinquet zu Recht sagte: „Wiederholen Sie nicht. Erstens, du wiederholst dich, zweitens, du sagst dasselbe und drittens, jeder hat das schon gehört. “

Erinnern Sie sich, wir sprachen über die Wiederverwendung, die spontan auftritt? Genau dies (und nur dies) sollte auf den Zweck des ergonomischen Codes beschränkt sein. Schreiben Sie also den Code, den Sie in diesem bestimmten Moment benötigen, und fahren Sie im gleichen Geist fort, bis Sie feststellen, dass Sie das gleiche Problem immer wieder lösen müssen. Führen Sie dann das Refactoring durch, platzieren Sie den Code an einem zugänglichen Ort und beziehen Sie sich bei Bedarf darauf. Auf diese Weise erhalten Sie keinen verschwenderischen verallgemeinerten Code, sondern einen Code, in dem es keine Duplizierung gibt.

In der Tat wird dasselbe Prinzip vom DRY-Prinzip postuliert (wiederholen Sie sich nicht), das besagt, dass dieselbe Logik nicht wiederholt in den Code geschrieben werden sollte - dies führt zu einer technischen Pflicht. Sinnlose Wiederholungen verstopfen das System, verringern die Qualität der Codebasis und machen sie außerdem zu einem Albtraum für diejenigen, die für die Pflege des Produktcodes verantwortlich sind. Es ist wichtig, sich daran zu erinnern: Das DRY-Prinzip ist eine Art Philosophie, die dazu auffordert, persönliche Programmierambitionen aufzugeben und das zu tun, was für das Projekt am besten ist. Wenn jemand schon etwas getan hat, benutze es. Das Rad muss nicht neu erfunden werden.

Stellen Sie sicher, dass die Klasse / Methode / Funktion für eine Sache verantwortlich ist.


Bei dieser Gelegenheit können wir uns an die schöne Aussage von Louis Sullivan erinnern: "Form kommt vom Bestimmungsort." In der Übersetzung bedeutet dies Folgendes: Wenn eine Funktion, Klasse oder Methode das Einzige tut, werden Sie sie aus nur einem Grund ändern. Ja, mit diesem Ansatz müssen Sie häufig Methoden erstellen, die andere Methoden verwenden, aber sie bleiben einfach und nicht zu kohärent.

Jedes System basiert auf einer fachorientierten Sprache, die von Programmierern mit dem Ziel erstellt wurde, solche Systeme richtig zu beschreiben. Funktionen erfüllen die Rolle von Verben in diesen Sprachen und Klassen spielen die Rolle von Substantiven. Zusammen bilden sie in der Regel die Grundorganisationsebene einer Sprache. Dementsprechend ist Ihr Code von hoher Qualität, wenn Sie ihn qualitativ verschreiben.

Es gibt zwei goldene Regeln für das Erstellen von Funktionen und Klassen, die mehrfach angewendet werden können, nur zwei:

  • Sie sollten klein sein
  • Sie sollten eine Sache tun und gut

Dies setzt voraus, dass die Funktion nicht so groß werden sollte, dass sie verschachtelte Strukturen enthält. Das Verschachtelungsniveau sollte daher ein oder zwei nicht überschreiten. Dank dieser Technik ist der Code leichter zu lesen, zu analysieren und zu assimilieren.

Darüber hinaus muss sichergestellt werden, dass alle Operatoren innerhalb einer einzelnen Funktion auf derselben Abstraktionsebene bleiben. Das Mischen von Ebenen ist immer verwirrend und führt früher oder später zu harter Arbeit mit dem Code. Pro-Programmierer sehen reproduzierbaren Code als eine Art Erzählung, nicht nur als Text. Sie nutzen die Fähigkeiten der gewählten Programmiersprache, um ausdrucksvollere, aussagekräftigere und übersichtlichere Blöcke zu erstellen, die die Erzählung perfekt aufbauen.

Missbrauchen Sie nicht die Vererbung


Manchmal versuchen wir, die Entwickler, in die ferne Zukunft des Projekts zu blicken und beginnen, zusätzliche Funktionen mit den Gedanken „Was ist, wenn Sie es brauchen?“ Und „Irgendwann als nützlich erweisen?“ Hinzuzufügen. Nicht so. Bis jetzt hat sich dies nicht als nützlich für Sie erwiesen, jetzt brauchen Sie es nicht und in den meisten Fällen ... werden Sie es nicht brauchen (um das bekannte Prinzip von YAGNI zu umschreiben - Sie werden es nicht brauchen). Dieser Grundsatz gilt für die Vererbung. Geben Sie es nicht ein, wenn Sie nicht sicher sind, dass die Implementierung mehrmals wiederholt wird.

Mit all dem ist Vererbung eine großartige Möglichkeit, einer Klasse Funktionalität hinzuzufügen. Aber Programmierer neigen dazu, über den Rand zu greifen und Klassenhierarchien in sechs oder mehr Ebenen aufzubauen. Die "Viererbande" beschreibt in ihrem Buch "Design Patterns" kurz und bündig die Risiken einer übermäßigen Vererbung:

"Da die Unterklasse Zugriff auf Implementierungsdetails der übergeordneten Klasse hat, wird häufig behauptet, dass die Vererbung die Kapselung verletzt."

Vererbung führt zu einem starken Zusammenhalt der Komponenten, da die Oberklasse ihre Innenseiten für Unterklassen öffnet und diese wiederum in allem, was mit der korrekten Operation zu tun hat, vollständig von der Oberklasse abhängig sind. In dieser Situation verliert die Superklasse ihre Flexibilität - es wird schwierig, irgendetwas an ihrer Funktionalität zu ändern. Aus diesem Grund ist Vererbung ein schlechter Weg, um die Wiederverwendung von Code zu erreichen.

Ein vernünftigerer Ansatz besteht darin, im Paradigma der Objektstruktur zu denken und nicht in der Vererbung. Auf diese Weise können Benutzer, die Ihren Code verwenden, auf einfachere Weise genau die Funktionen nutzen, die sie benötigen, und ihre eigenen Objekte auf der Grundlage der für sie relevanten Einschränkungen erstellen. Sie sollten sogar in Betracht ziehen, prozedurale Schnittstellen zu erstellen, die jede Klasse auf ihre eigene Weise implementieren kann. Schnittstellen sind oft einfacher zu verstehen und zu implementieren als Klassen mit mehrschichtiger Vererbung.

Zusammenfassend sollte man nur dann auf Vererbung zurückgreifen, wenn eine Klasse eine logische Fortsetzung einer anderen ist und der Großteil des Codes der übernehmenden Klasse den Code der Oberklasse verwendet. In jedem anderen Fall unterschreiben Sie einfach das Todesurteil für sich selbst und die Chancen Ihres Wiederverwendungscodes.

Abschließend


Im Allgemeinen bedeutet das Schreiben von Code zur Wiederverwendung nicht, dass große generalisierte monolithische Blöcke erstellt werden. Der Schlüssel zum Schreiben von reproduzierbarem Code liegt in den Elementen, die auf eine bestimmte Aufgabe ausgerichtet sind, die leicht zusammengesetzt, gut verlötet und nicht zu fest miteinander verbunden werden können.

Und zum Schluss: Machen Sie sich bei wiederholtem Gebrauch keinen Selbstzweck - es lohnt sich nicht. Es ist besser, ein Ziel festzulegen, um Doppelungen zu vermeiden, und keine leeren, unnötigen Fragmente zu schreiben, um sicherzustellen, dass der Code einfach zu lesen und zu warten ist. Wenn Sie die richtige Sichtweise auf die Dinge entwickeln, wird die Reproduzierbarkeit von selbst kommen.

Denken Sie immer daran: Die Wiederverwendung beginnt damit, dass Sie für eine bestimmte Aufgabe eine erfolgreiche Lösung gefunden haben. Alles andere sollte von dieser Prämisse ausgehen, und Sie haben das Recht, die am besten geeignete Methode zu wählen, um ein bestimmtes Stück Code auf eine neue Ebene zu bringen. Wie Ralph Johnson zu Recht bemerkte: "Bevor Sie über die Wiederverwendung von Code nachdenken, müssen Sie sicherstellen, dass Sie ihn überhaupt verwenden können."

Source: https://habr.com/ru/post/de481296/


All Articles