Ich denke, Sie könnten einen Blog-Beitrag von mir über undichte Abstraktionen nützlich finden. Hier ist der relevante Hintergrund:
Die Abstraktion ist ein Mechanismus, der dabei hilft, die Gemeinsamkeiten einer Reihe verwandter Programmfragmente zu erkennen, ihre Unterschiede zu beseitigen und es Programmierern zu ermöglichen, direkt mit einem Konstrukt zu arbeiten, das dieses abstrakte Konzept darstellt. Dieses neue Konstrukt weist (praktisch) immer Parametrisierungen auf : eine Möglichkeit, die Verwendung des Konstrukts an Ihre spezifischen Anforderungen anzupassen.
Eine List
Klasse kann beispielsweise die Details einer Implementierung mit verknüpften Listen abstrahieren. Anstatt über Manipulationen next
und previous
Zeiger nachzudenken, können Sie überlegen , ob einer Sequenz Werte hinzugefügt oder daraus entfernt werden sollen. Abstraktion ist ein wesentliches Werkzeug, um nützliche, reichhaltige und manchmal komplexe Merkmale aus einer viel kleineren Menge primitiverer Konzepte zu erstellen.
Abstraktion ist mit Kapselung und Modularität verbunden, und diese Konzepte werden oft missverstanden.
In diesem List
Beispiel kann die Kapselung verwendet werden, um die Implementierungsdetails einer verknüpften Liste auszublenden. In einer objektorientierten Sprache können Sie beispielsweise den Zeiger next
und als previous
privat kennzeichnen, wobei nur die List-Implementierung Zugriff auf diese Felder hat.
Die Verkapselung reicht für die Abstraktion nicht aus, da dies nicht unbedingt impliziert, dass Sie eine neue oder andere Konzeption der Konstrukte haben. Wenn eine List
Klasse nur Zugriffsmethoden im ' getNext
' / ' setNext
' - Stil zur Verfügung stellen würde, würde sie die Implementierungsdetails von Ihnen kapseln (z. B. haben Sie das Feld ' prev
' oder ' previous
' benannt? Welchen statischen Typ hat es?), Aber es hätte einen sehr geringen Abstraktionsgrad.
Die Modularität betrifft das Ausblenden von Informationen : In einer Schnittstelle werden stabile Eigenschaften angegeben, und ein Modul implementiert diese Schnittstelle, wobei alle Implementierungsdetails innerhalb des Moduls erhalten bleiben. Die Modularität hilft Programmierern, mit Veränderungen umzugehen, da andere Module nur von der stabilen Schnittstelle abhängen.
Das Ausblenden von Informationen wird durch die Kapselung unterstützt (sodass Ihr Code nicht von instabilen Implementierungsdetails abhängt), die Kapselung ist jedoch aus Gründen der Modularität nicht erforderlich. Zum Beispiel können Sie eine Implementierung List
Struktur in C, das Aussetzen der ‚ next
‘ und ‚ prev
‘ Zeiger auf die Welt, sondern auch eine Schnittstelle bereitstellen, enthält initList()
, addToList()
undremoveFromList()
funktionen. Unter der Voraussetzung, dass die Regeln der Schnittstelle eingehalten werden, können Sie sicherstellen, dass bestimmte Eigenschaften immer gültig sind, beispielsweise, dass die Datenstruktur immer gültig ist. [Parnas 'klassisches Papier über Modularität wurde zum Beispiel mit einem Beispiel in der Montage geschrieben. Die Schnittstelle ist ein Vertrag und eine Form der Kommunikation über das Design, sie muss nicht unbedingt mechanisch überprüft werden, obwohl wir uns heute darauf verlassen.]
Obwohl Begriffe wie abstrakt, modular und gekapselt als positive Designbeschreibungen verwendet werden, ist es wichtig zu wissen, dass das Vorhandensein einer dieser Eigenschaften nicht automatisch zu einem guten Design führt:
Wenn ein n ^ 3-Algorithmus "gut gekapselt" ist, arbeitet er immer noch schlechter als ein verbesserter n log n-Algorithmus.
Wenn eine Schnittstelle für ein bestimmtes Betriebssystem festgeschrieben ist, wird keiner der Vorteile eines modularen Designs realisiert, wenn beispielsweise ein Videospiel von Windows auf das iPad portiert werden muss.
Wenn die erstellte Abstraktion zu viele unwesentliche Details enthält, kann sie kein neues Konstrukt mit eigenen Operationen erstellen: Es wird einfach ein anderer Name für dieselbe Sache sein.