Wann soll abstrakter Code geschrieben und wann genauer?

9

Ich arbeite an einem kleinen Tool als Spielzeugprojekt, um den Unterschied zwischen zwei Verzeichnissen aufzuzeigen und zu zeigen, welche Dateien / Verzeichnisse hinzugefügt, entfernt, geändert usw. wurden.

Ich habe versucht, diese Änderungen einfach als 'ChangeItem'-Objekte darzustellen, ohne zu unterscheiden, ob es sich um eine Datei oder ein Verzeichnis handelt. Dies führte jedoch zu vielen Problemen, z. B. wie man sie in einem Baum anzeigt, wie man weiß, wer die Eltern eines Kindes sind usw. Und es war auch sehr unintuitiv.

Ich habe dann die Änderungen zwischen Verzeichnisänderungen und Dateiänderungen aufgeteilt. Das machte es sofort sehr einfach zu codieren und zu verstehen, was los war. Jetzt ist es viel einfacher, alle Dateien in einem Verzeichnis usw. auszuwählen.

Meine Frage ist, wie kann man wissen, ob man Abstraktion verwendet oder spezifischer in ihrem Code wird? Wie können Sie feststellen, ob Sie zu viel oder zu wenig Abstraktion haben?

Klicken Sie auf Upvote
quelle

Antworten:

9

Woher weiß ein Maler, ob es zu viel oder zu wenig Purpur ist?

Er mischt die Farben, versucht einen Strich, macht ein paar Skizzen und sieht, was passiert. Dann passt er die Proportionen an, bis die gesamte Zeichnung gut aussieht und Harmonie ausstrahlt.

Wir machen das gleiche mit Code. Wir bekommen eine erste Implementierungsidee, reflektieren sie, analysieren ihre Stärken und Wochen und versuchen sie dann, um zu sehen, ob sie funktioniert. Dann stimmen wir die Idee in einem iterativen Prozess ab, um die Proportionen von Abstraktheit, Kapselung, Polymorphismus und was auch immer anzupassen, bis sie richtig aussieht und nach Bedarf funktioniert.


quelle
21

Sie schreiben zuerst konkreten Code.

Sie schreiben abstrakten Code, wenn Sie müssen, weil er konkreten Code vereinfacht.

Es ist am einfachsten, mit Beton zu beginnen und die Abstraktionen zu finden, nachdem Sie untersucht haben, was am Beton ähnlich und anders ist.

S.Lott
quelle
13
Denken Sie immer an die Dreierregel: Eine Abstraktion ohne mindestens drei Clients ist keine Abstraktion. Es ist Wunschdenken. Normalerweise falsch. Gute Abstraktion wird extrahiert , nicht entworfen.
Jörg W Mittag
3

Sie schreiben abstrakten Code, wenn Sie Bibliotheken schreiben, und müssen die Funktionalität verallgemeinern, damit sie unter einer Vielzahl von Bedingungen funktioniert.

Aber das Schreiben von Bibliotheken auf diese Weise ist schwierig. In einer normalen Anwendung (z. B. einer Branchenanwendung) wird diese Art der Verallgemeinerung als eine Form der "vorzeitigen Optimierung" angesehen, die im Allgemeinen als "Sie werden sie nicht benötigen" (YAGNI) bezeichnet wird.

Es gibt einen Wendepunkt, an dem sich wiederholender Code die Entwicklung einer allgemeineren Lösung erfordert. In der Regel ist diese Art der Umgestaltung zum Entfernen von Redundanz jedoch viel einfacher als das Schreiben einer verallgemeinerten Bibliothek.

Letztendlich muss die zusätzliche Komplexität, die für die Implementierung abstrakter Lösungen erforderlich ist, durch die Flexibilität gerechtfertigt sein, die sie bieten.

Robert Harvey
quelle
3

Die Faustregel, der ich folge, die ziemlich häufig ist, ist, dass Sie nicht versuchen sollten, etwas zu abstrahieren, bis Sie es zum dritten Mal schreiben.

Das erste Mal, wenn Sie die Problemdomäne einfach nicht verstehen, werden Sie die falschen Teile überarchitekturieren. Beim zweiten Mal sind Sie perfekt positioniert, um die ideale Lösung für Ihr letztes Problem zu finden. Das dritte Mal sind Sie endlich in der Lage, geeignete Abstraktionen zu entwickeln, die Ihnen bei Dingen helfen, die geändert werden müssen, und Sie nicht daran hindern, die einfachen Dinge zu erledigen.

Übrigens
quelle
1
Das 3. Mal ist eine gute Faustregel. Ich finde es selten, sehr viel zu verallgemeinern, bevor ich zum dritten Mal etwas schreibe.
Quentin-Starin
1
Kommt es nicht auch darauf an, wie groß der ähnliche Code ist? Sie würden nicht zwei Seiten Code kopieren und einfügen, die sich nur um zwei Zeilen unterscheiden, nur weil Sie das magische "3-mal" noch nicht getroffen haben.
Scott Whitlock
@ Scott-Whitlock: Offensichtlich. Deshalb ist es eine Faustregel. Ignorieren Sie es entsprechend. Darüber hinaus gibt es einen Unterschied zwischen organischen Abstraktionen (z. B. "Ich brauchte einen Balken, um fast genau foo zu sein, also habe ich foo nur einen optionalen Parameter hinzugefügt") und Abstraktionen, die Teil Ihres Up-Front-Designs sind.
Btilly
1
@ Scott Whitlock: "Sie würden nicht zwei Seiten Code kopieren und einfügen, die sich nur um zwei Zeilen unterscheiden." Das ist kein Aufruf zur Abstraktion. Das ist immer noch gutes Design. Die 3x-Regel muss sehr, sehr streng eingehalten werden, um vorzeitig abstrakte Designs zu vermeiden.
S.Lott
"Nach Bedarf" ist hier der Schlüsselbegriff. Meine zwei Cent - oft gilt die "Komposition der Vererbung vorziehen". Manchmal wäre ein Problem, das manche mit einer Abstraktion lösen, besser als if (cond) { //use one object} else {// use the other object }, insb. wenn es ein binärer Entscheidungssatz ist.
Michael K
2

Wenn ich die Frage lese, würde ich sagen, dass Sie sowohl abstrakt als auch spezifisch sein können. Ist nur eine Frage des Kontexts, verwenden Sie in jedem Kontext die abstrakteste Darstellung, die möglich ist.

Ist für Ihre spezifische Spielzeug-App ChangeItemdie abstrakteste Darstellung der Änderungen. Dann werden Sie mit DirectoryChangeItemund FileChangeItemdurch Vererbung spezifischer . Sie können ein zusammengesetztes Muster verwenden , um den Baum zu modellieren. Wenn Sie es anzeigen möchten, können Sie die spezifischen Darstellungen verwenden, und wenn Sie es durchlaufen, können Sie die abstrakte Darstellung verwenden.

Und um eine konkrete Antwort auf die Frage zu geben: Seien Sie so genau wie möglich, bis Sie das Gefühl haben, dass Sie eine weitere Schicht darunter benötigen.

Victor Hurdugaci
quelle
1

In der Regel ist Abstraktion nützlich, um Dinge wie Komplexität und Entropie zu bekämpfen, Ihren Code kybernetisch zu machen und sogar bei geringer Lesbarkeit. Ich würde zuerst hart codieren - NUR, wenn die Abstraktion von vornherein nicht offensichtlich ist. Die meiste Abstraktion tritt auf, wenn mehr als eine Implementierung dasselbe Muster verwenden.

Stellen Sie sich Abstraktion als Kongruenz oder Einheit von zwei oder mehr Mengen vor. Nehmen Sie ein Venn-Diagramm als vereinfachtes Modell: Der Teil, in dem sich die Kreise überlappen, oder mit anderen Worten, die Sets werden zusammengeführt.

Wenn ich zwei Mengen habe: A: {a, b, c, d, e} und B: {d, e, f, g, h}. Der Punkt, an dem ich anfangen würde, abstrakt zu suchen, ist die Einheit von A + B; {d, e} ist der Ort, an dem abstrahiert werden soll. In ähnlicher Weise würde ich die Abstraktion beibehalten, wenn diejenigen in der Differenz von A & B (AB oder BA) isomorph zueinander sind, was bedeutet, dass es kostengünstig ist, a, b oder c aus f, g oder h (und umgekehrt) zu erstellen im Hinterkopf.

Cody
quelle