it-swarm.com.de

Bedeutung der undichten Abstraktion?

Was bedeutet der Begriff "Undichte Abstraktion"? (Bitte erläutern Sie dies anhand von Beispielen. Es fällt mir oft schwer, eine bloße Theorie zu verstehen.)

63
Geonne

Hier ist ein Meatspace Beispiel:

Autos haben Abstraktionen für Autofahrer. In seiner reinsten Form gibt es Lenkrad, Gaspedal und Bremse. Diese Abstraktion verbirgt viele Details über das, was sich unter der Haube befindet: Motor, Nocken, Zahnriemen, Zündkerzen, Kühler usw.

Das Schöne an dieser Abstraktion ist, dass wir Teile der Implementierung durch verbesserte Teile ersetzen können, ohne den Benutzer neu schulen zu müssen. Nehmen wir an, wir ersetzen die Verteilerkappe durch eine elektronische Zündung und die feste Nocke durch eine variable Nocke. Diese Änderungen verbessern die Leistung, aber der Benutzer lenkt immer noch mit dem Rad und verwendet die Pedale zum Starten und Stoppen.

Es ist wirklich bemerkenswert ... Ein 16-jähriger oder ein 80-jähriger kann dieses komplizierte Gerät bedienen, ohne wirklich viel darüber zu wissen, wie es im Inneren funktioniert!

Aber es gibt Undichtigkeiten. Die Übertragung ist ein kleines Leck. In einem Automatikgetriebe spürt man, wie das Fahrzeug für einen Moment an Kraft verliert, wenn es die Gänge wechselt, wohingegen in CVT ein sanftes Drehmoment den ganzen Weg nach oben spürt.

Es gibt auch größere Lecks. Wenn Sie den Motor zu schnell drehen, können Sie ihn beschädigen. Wenn der Motorblock zu kalt ist, startet das Fahrzeug möglicherweise nicht oder hat eine schlechte Leistung. Wenn Sie gleichzeitig Radio, Scheinwerfer und Wechselstrom drehen, werden Ihre Benzinverbrauchszahlen sinken.

79
Mark E. Haase

Es bedeutet einfach, dass Ihre Abstraktion einige der Implementierungsdetails freigibt oder dass Sie die Implementierungsdetails kennen müssen, wenn Sie die Abstraktion verwenden. Der Begriff wird Joel Spolsky , circa 2002. zugeschrieben. Weitere Informationen finden Sie im Wikipedia Artikel .

Ein klassisches Beispiel sind Netzwerkbibliotheken, mit denen Sie Remote-Dateien als lokal behandeln können. Der Entwickler, der diese Abstraktion verwendet, muss sich bewusst sein, dass Netzwerkprobleme dazu führen können, dass dies auf eine Weise fehlschlägt, die lokale Dateien nicht tun. Sie müssen dann Code entwickeln, um speziell Fehler außerhalb der Abstraktion der Netzwerkbibliothek zu behandeln.

39
tvanfosson

Wikipedia hat eine ziemlich gute Definition

Eine undichte Abstraktion bezieht sich auf jede implementierte Abstraktion, mit der die Komplexität verringert (oder ausgeblendet) werden soll, bei der die zugrunde liegenden Details nicht vollständig verborgen sind

Mit anderen Worten: Bei Software können Sie Implementierungsdetails eines Features über Einschränkungen oder Nebenwirkungen im Programm beobachten. 

Ein schnelles Beispiel wären C #/VB.Net-Verschlüsse und deren Unfähigkeit, Ref/Out-Parameter zu erfassen. Der Grund, warum sie nicht erfasst werden können, liegt in einem Implementierungsdetail, wie der Hebevorgang abläuft. Das heißt nicht, dass es einen besseren Weg gibt, dies zu tun. 

12
JaredPar

Hier ist ein Beispiel, das .NET-Entwicklern vertraut ist: Die Page-Klasse von ASP.NET versucht, die Details von HTTP-Vorgängen, insbesondere die Verwaltung von Formulardaten, auszublenden, sodass Entwickler sich nicht mit veröffentlichten Werten befassen müssen (da sie Formularwerte automatisch zuordnen Serversteuerungen).

Wenn Sie jedoch über die grundlegendsten Verwendungsszenarien hinausgehen, beginnt die Page-Abstraktion undicht zu werden, und es wird schwierig, mit Seiten zu arbeiten, es sei denn, Sie kennen die Implementierungsdetails der Klasse.

Ein allgemeines Beispiel ist das dynamische Hinzufügen von Steuerelementen zu einer Seite. Der Wert von dynamisch hinzugefügten Steuerelementen wird für Sie nicht zugeordnet, es sei denn, Sie fügen sie um genau zum richtigen Zeitpunkt: hinzu, bevor das zugrunde liegende Modul die eingehenden Formularwerte zuordnet zu den entsprechenden Kontrollen. Wenn Sie das lernen müssen, hat die Abstraktion durchgesickert.

11
Jeff Sternal

In gewisser Weise ist es eine rein theoretische Sache, wenn auch nicht unwichtig.

Wir verwenden Abstraktionen, um die Dinge leichter verständlich zu machen. Ich kann eine String-Klasse in einer Sprache verwenden, um die Tatsache zu verbergen, dass es sich um eine geordnete Menge von Zeichen handelt, die einzelne Elemente sind. Ich beschäftige mich mit einer geordneten Gruppe von Zeichen, um die Tatsache zu verbergen, dass es sich um Zahlen handelt. Ich beschäftige mich mit Zahlen, um die Tatsache zu verbergen, dass es sich um 1 und 0 handelt.

Eine undichte Abstraktion ist eine, die die Details nicht verdeckt. Wenn der Aufruf string.Length für eine 5-stellige Zeichenfolge in Java oder .NET ist, könnte ich aufgrund von Implementierungsdetails, bei denen die Zeichen als Sprachzeichen bezeichnet werden, wirklich UTF-16-Datenpunkte sein, die entweder 1 oder darstellen können .5 eines Charakters. Die Abstraktion ist durchgesickert. Wenn es nicht ausläuft, bedeutet dies, dass das Auffinden der Länge entweder mehr Speicherplatz (zum Speichern der tatsächlichen Länge) erfordert oder von O(1) zu O(n) (zur Arbeit) wechselt heraus, was die wirkliche Länge ist). Wenn mir die eigentliche Antwort wichtig ist (oft tun Sie dies nicht wirklich), müssen Sie an dem Wissen darüber arbeiten, was wirklich vor sich geht.

Umstrittenere Fälle treten auf, wenn zum Beispiel eine Methode oder eine Eigenschaft Sie in die inneren Abläufe einlässt, ob es sich um Abstraktionslecks handelt oder um genau definierte Wege, um auf eine niedrigere Abstraktionsebene zu gelangen. Dies ist manchmal eine Angelegenheit, über die die Menschen nicht einig sind.

7
Jon Hanna

Ich werde weitermachen, indem ich mit Hilfe von RPC Beispiele gebe.

In der idealen Welt von RPC sollte ein Remoteprozeduraufruf wie ein lokaler Prozeduraufruf aussehen (oder so geht es weiter). Sie sollte für den Programmierer vollständig transparent sein, so dass sie beim Aufruf von SomeObject.someFunction() keine Ahnung haben, ob SomeObject (oder nur someFunction) lokal gespeichert und ausgeführt oder remote gespeichert und ausgeführt wird. Die Theorie besagt, dass dies die Programmierung vereinfacht.

Die Realität ist anders, weil es einen RIESEN Unterschied gibt zwischen dem Aufruf einer lokalen Funktion (selbst wenn Sie die langsamste interpretierte Sprache der Welt verwenden) und:

  • aufruf über ein Proxy-Objekt
  • serialisierung Ihrer Parameter
  • herstellen einer Netzwerkverbindung (falls noch nicht hergestellt)
  • Übertragen der Daten an den Remote-Proxy
  • der Remote-Proxy muss die Daten wiederherstellen und die Remote-Funktion in Ihrem Namen aufrufen
  • serialisierung der Rückgabewerte
  • Übertragen der Rückgabewerte an den lokalen Proxy
  • zusammensetzen der serialisierten Daten
  • rückgabe der Antwort von der Remote-Funktion

Allein in der Zeit sind das etwa drei Größenordnungen (oder mehr!). Diese drei Größenordnungen werden einen großen Unterschied in der Leistung bewirken, was die Abstraktion eines Prozeduraufforderungslecks eher offensichtlich macht, wenn Sie einen RPC zum ersten Mal fälschlicherweise als einen echten Funktionsaufruf behandeln. Ein echter Funktionsaufruf, der ernsthafte Probleme in Ihrem Code ausschließt, hat nur wenige Fehlerpunkte außerhalb von Implementierungsfehlern. Ein RPC-Anruf hat alle folgenden möglichen Probleme, die über das hinausgehen, was Sie von einem normalen Ortsgespräch erwarten würden, als Fehlerfälle.

  • sie können Ihren lokalen Proxy möglicherweise nicht instanziieren
  • sie können den Remote-Proxy möglicherweise nicht instanziieren
  • die Proxys können möglicherweise keine Verbindung herstellen
  • die Parameter, die Sie senden, machen sie möglicherweise nicht oder überhaupt nicht intakt
  • der Rückgabewert, den die Fernbedienung sendet, macht ihn möglicherweise nicht oder überhaupt nicht intakt

Ihr RPC-Aufruf, der "wie ein lokaler Funktionsaufruf" ist, hat also eine ganze Reihe zusätzlicher Fehlerbedingungen, mit denen Sie nicht konfrontiert werden müssen, wenn Sie lokale Funktionsaufrufe durchführen. Die Abstraktion ist noch schwieriger geworden.

Am Ende ist RPC eine schlechte Abstraktion, da es auf jeder Ebene wie ein Sieb ausläuft - wenn es erfolgreich ist und wenn beide ausfallen.

Ein Beispiel im Django ORM Many-to-Many-Beispiel :

Beachten Sie in der Beispiel-API-Verwendung, dass Sie .save () das Artikel-Basisobjekt a1 vor dem Hinzufügen von Publication-Objekten zum Many-to-Many-Attribut benötigen. Beachten Sie, dass die Aktualisierung des Many-to-Many-Attributs sofort in der zugrunde liegenden Datenbank gespeichert wird, während die Aktualisierung eines einzelnen Attributs in der Datenbankbibliothek erst nach Aufruf von .save () wiedergegeben wird. 

Die Abstraktion ist, dass wir mit einem Objektdiagramm arbeiten, bei dem einwertige Attribute und mehrwertige Attribute nur Attribute sind. Die Implementierung als relationaler, datenbankgestützter Datenspeicher leckt jedoch ... da das Integritätssystem der RDBS durch das dünne Furnier einer Objektschnittstelle erscheint.

2
hash1baby

Die Tatsache, dass irgendwann , die von Ihrem Umfang und Ihrer Ausführung abhängen wird, wird erforderlich sein, um sich mit den Implementierungsdetails Ihres Abstraktionsframeworks vertraut zu machen, um zu verstehen, warum es sich so verhält.

Betrachten Sie zum Beispiel diese SQL-Abfrage:

SELECT id, first_name, last_name, age, subject FROM student_details;

Und es ist alternativ:

SELECT * FROM student_details;

Jetzt sehen sie aus wie eine logisch äquivalente Lösung, aber die Leistung der ersten ist aufgrund der Spezifikation der einzelnen Spaltennamen besser. 

Es ist ein triviales Beispiel, aber irgendwann kommt es zurück zu Joel Spolskys Zitat:

Alle nicht-trivialen Abstraktionen sind bis zu einem gewissen Grad undicht.

Wenn Sie zu einem bestimmten Zeitpunkt in Ihrem Betrieb einen bestimmten Umfang erreichen, sollten Sie die Funktionsweise Ihrer DB (SQL) optimieren. Dazu müssen Sie wissen, wie relationale Datenbanken funktionieren. Sie wurde am Anfang zu Ihnen abstrahiert, aber es ist undicht. Sie müssen es irgendwann lernen.

0
Stas