web-dev-qa-db-de.com

Was ist der Unterschied zwischen Objekten und Datenstrukturen?

Ich habe das Buch Clean Code: Ein Handbuch für agile Software Handwerkskunst gelesen und in Kapitel 6, Seiten 95-98, werden die Unterschiede zwischen Objekten und Datenstrukturen erläutert

  • Objekte verbergen ihre Daten hinter Abstraktionen und machen Funktionen verfügbar, die mit diesen Daten arbeiten. Datenstrukturen machen ihre Daten verfügbar und haben keine sinnvollen Funktionen.

  • Objekt exponieren Verhalten und verstecken Daten. Dadurch können Sie leicht neue Arten von Objekten hinzufügen, ohne das vorhandene Verhalten zu ändern. Außerdem ist es schwierig, vorhandenen Objekten neue Verhaltensweisen hinzuzufügen.

  • Datenstrukturen machen Daten verfügbar und haben kein signifikantes Verhalten. Dadurch können vorhandene Datenstrukturen problemlos mit neuen Verhaltensweisen versehen werden, bestehende Funktionen können jedoch nicht mit neuen Datenstrukturen versehen werden.

Ich bin ein bisschen verwirrt, ob einige Klassen Objekte oder Datenstrukturen sind. Sagen wir zum Beispiel HashMaps in Java.util, sind das Objekte? (aufgrund ihrer Methoden wie put (), get () kennen wir ihre inneren Abläufe nicht) oder sind sie Datenstrukturen? (Ich habe es immer als Datenstrukturen betrachtet, weil es eine Map ist). 

Auch Strings, sind dies Datenstrukturen oder Objekte?

Bisher waren die meisten Code, den ich geschrieben habe, die sogenannten "Hybridklassen", die versuchen, als Objekt und als Datenstruktur zu fungieren. Irgendwelche Tipps, wie man sie auch vermeiden kann?

27

Die Unterscheidung zwischen Datenstrukturen und Klassen/Objekten ist in Java) schwerer zu erklären als in C++. In C gibt es keine Klassen, nur Datenstrukturen, die nichts anderes als "Container" von typisierte und benannte Felder. C++ hat diese "Strukturen" geerbt, sodass Sie sowohl "klassische" Datenstrukturen als auch "echte Objekte" haben können.

In Java können Sie Datenstrukturen im C-Stil mit Klassen "emulieren", die keine Methoden und nur öffentliche Felder haben:

public class VehicleStruct
{
    public Engine engine;
    public Wheel[] wheels;
}

Ein Benutzer von VehicleStruct kennt die Teile, aus denen ein Fahrzeug besteht, und kann direkt mit diesen Teilen interagieren. Verhalten, d. H. Funktionen, müssen außerhalb der Klasse definiert werden. Aus diesem Grund ist es einfach, das Verhalten zu ändern: Das Hinzufügen neuer Funktionen erfordert keine Änderung des vorhandenen Codes. Das Ändern von Daten erfordert andererseits Änderungen in praktisch jeder Funktion, die mit VehicleStruct interagiert. Es verletzt die Kapselung!

Die Idee hinter OOP ist, die Daten zu verbergen und stattdessen das Verhalten offenzulegen. Sie konzentriert sich auf das, was Sie mit tun können Fahrzeug, ohne zu wissen, ob es einen Motor hat oder wie viele Räder eingebaut sind:

public class Vehicle
{
    private Details hidden;

    public void startEngine() { ... }
    public void shiftInto(int gear) { ... }
    public void accelerate(double amount) { ... }
    public void brake(double amount) { ... }
}

Beachten Sie, wie das Vehicle ein Motorrad, ein Auto, ein Lastwagen oder ein Panzer sein kann - Sie müssen die Details nicht kennen. Das Ändern von Daten ist einfach - niemand außerhalb der Klasse kennt sich mit Daten aus, sodass kein Benutzer der Klasse geändert werden muss. Das Ändern des Verhaltens ist schwierig: Alle Unterklassen müssen angepasst werden, wenn der Klasse eine neue (abstrakte) Funktion hinzugefügt wird.

Wenn Sie nun die "Regeln der Kapselung" befolgen, können Sie das Ausblenden der Daten so verstehen, dass Sie die Felder einfach privat machen und Accessormethoden zu VehicleStruct hinzufügen:

public class VehicleStruct
{
    private Engine engine;
    private Wheel[] wheels;

    public Engine getEngine() { return engine; }
    public Wheel[] getWheels() { return wheels; }
}

In seinem Buch argumentiert Onkel Bob, dass Sie auf diese Weise immer noch eine Datenstruktur und kein Objekt haben. Sie modellieren das Fahrzeug immer noch nur als die Summe seiner Teile und legen diese Teile mithilfe von Methoden offen. Es ist im Wesentlichen dasselbe wie die Version mit öffentlichen Feldern und einem einfachen alten C struct - daher eine Datenstruktur. Das Ausblenden von Daten und das Offenlegen von Methoden reicht nicht aus, um ein Objekt zu erstellen. Sie müssen prüfen, ob die Methoden tatsächlich das Verhalten oder nur die Daten offenlegen!

Wenn Sie die beiden Ansätze mischen, z. Wenn Sie getEngine() zusammen mit startEngine() aussetzen, erhalten Sie einen "Hybrid". Ich habe Martins Buch nicht zur Hand, aber ich erinnere mich, dass er Hybriden überhaupt nicht empfohlen hat, da Sie das Schlimmste aus beiden Welten haben: Objekte, bei denen Daten und Verhalten nur schwer zu ändern sind.

Ihre Fragen zu HashMaps und Strings sind etwas knifflig, da diese ziemlich niedrig sind und nicht gut zu den Klassen passen, die Sie für Ihre Anwendungen schreiben werden. Unter Verwendung der oben angegebenen Definitionen sollten Sie jedoch in der Lage sein, diese zu beantworten.

Ein HashMap ist ein Objekt. Es enthüllt Ihnen sein Verhalten und verbirgt alle bösen Hashing-Details. Sie teilen es den Daten put und get mit, und es ist egal, welche Hash-Funktion verwendet wird, wie viele "Buckets" es gibt und wie mit Kollisionen umgegangen wird. Tatsächlich verwenden Sie HashMap nur über die Map-Schnittstelle, die ein gutes Indiz für Abstraktion und "echte" Objekte ist.

Seien Sie nicht verwirrt, dass Sie Instanzen einer Map als Ersatz für eine Datenstruktur verwenden können!

// A data structure
public class Point {
    public int x;
    public int y;
}

// A Map _instance_ used instead of a data structure!
Map<String, Integer> data = new HashMap<>();
data.put("x", 1);
data.put("y", 2);

Ein String dagegen ist so ziemlich ein Array von Zeichen und versucht nicht, dies sehr zu verbergen. Ich denke, man könnte es eine Datenstruktur nennen, aber um ehrlich zu sein, bin ich mir nicht sicher, ob auf die eine oder andere Weise viel gewonnen werden soll.

26
Ferdinand Beyer

Ein Objekt ist eine Instanz einer Klasse. Eine Klasse kann verschiedene Dinge aus der realen Welt modellieren. Es ist eine Abstraktion von etwas (Auto, Steckdose, Karte, Verbindung, Schüler, Lehrer, Sie nennen es).

Eine Datenstruktur ist eine Struktur, die bestimmte Daten auf eine bestimmte Weise organisiert. Sie können Strukturen auf andere Weise implementieren, als indem Sie Klassen verwenden (dies tun Sie in Sprachen, die OOP nicht unterstützen Implementieren Sie noch eine Datenstruktur in C (sagen wir mal).

HashMap in Java ist eine Klasse, die eine Kartendatenstruktur mithilfe einer Hash-basierten Implementierung modelliert. Daher wird sie HashMap genannt.

Socket in Java ist eine Klasse, die keine Datenstruktur modelliert, sondern etwas anderes (ein Socket). 

4
peter.petrov

Ich glaube, Robert. C. Martin versuchte zu vermitteln:

  1. Datenstrukturen sind Klassen, die einfach als Container strukturierter Daten dienen. Zum Beispiel:

    public class Point {
        public double x;
        public double y;
    }
    
  2. Objekte hingegen werden zum Erzeugen von Abstraktionen verwendet. Eine Abstraktion wird verstanden als:

    eine Vereinfachung von etwas viel Komplizierterem, das unter der Decke abläuft The Law of Leaky Abstractions, Joel über Software

    Daher verbergen Objekte alle ihre Untergründe und lassen Sie nur das Wesen ihrer Daten auf vereinfachte Weise manipulieren. Zum Beispiel:

    public interface Point {
        double getX();
        double getY();
        void setCartesian(double x, double y);
        double getR();
        double getTheta();
        void setPolar(double r, double theta);
    }
    

    Wo wir nicht wissen, wie der Punkt implementiert ist, aber wir wissen, wie verbrauchen es ist.

3
Enrique

Wie ich es verstehe, möchte Robert Martin vermitteln, dass Objekte ihre Daten nicht über Getter und Setter freigeben sollten, es sei denn, ihr einziger Zweck besteht darin, als einfache Datenbehälter zu fungieren. Gute Beispiele für solche Container sind Java-Beans, Entitätsobjekte (aus der Objektzuordnung von DB-Entitäten) usw.

Die Java Collection Framework-Klassen sind jedoch kein gutes Beispiel dafür, worauf er sich bezieht, da sie ihre internen Daten nicht wirklich offenlegen (was in vielen Fällen grundlegende Arrays ist). Es bietet eine Abstraktion, mit der Sie die darin enthaltenen Objekte abrufen können. Sie passen also (in meinem POV) in die Kategorie "Objekte".

Die Gründe dafür werden in den Zitaten angegeben, die Sie aus dem Buch hinzugefügt haben. Es gibt jedoch mehr gute Gründe, die Interna nicht offenzulegen. Klassen, die Getter und Setter anbieten, fordern beispielsweise Verstöße gegen das Demetergesetz. Darüber hinaus verringert das Wissen um die Struktur des Status einer Klasse (das Wissen, welche Getter/Setter sie hat) die Fähigkeit, die Implementierung dieser Klasse zu abstrahieren. Es gibt viele weitere Gründe dafür.

3
eitanfar

Eine Datenstruktur ist buchstäblich eine strukturierte Darstellung einiger Daten. Es gibt kein eingebautes "Wissen" außer der Struktur und der Benennung der Daten. Ein Objekt ist viel allgemeiner und kann eigentlich fast jede Entität in Ihrem System sein, die eine Schnittstelle für die Interaktion bietet und in verschiedenen Kontexten verwendet werden kann. Ein traditionelles class object kann beispielsweise Daten und geeignete Methoden für den Zugriff auf die Daten enthalten, und diese Daten können objektinstanzspezifisch (pro Instanz) oder Klassenebene sein.

Ich bin nicht sicher, ob der Begriff "Hybridklasse" auf der Beschreibung basiert, als Objekt oder Datenstruktur zu fungieren, da eine Klasse häufig Daten enthält. Diese Terminologie scheint also überflüssig.

1
lurker

Eine Datenstruktur ist nur eine Abstraktion, eine besondere Art, Daten darzustellen. Sie sind nur von Menschen gemachte Konstrukte, die dazu beitragen, die Komplexität auf hoher Ebene zu reduzieren, d. H. Nicht auf niedriger Ebene zu arbeiten. Ein Objekt scheint das gleiche zu bedeuten, aber der Hauptunterschied zwischen Objekten und Datenstrukturen besteht darin, dass ein Objekt etwas abstrahieren kann. Es bietet auch Verhalten. Eine Datenstruktur hat kein Verhalten, da es sich nur um Datenspeicher handelt. 

Die Bibliotheksklassen wie Map, List usw. sind Klassen, die Datenstrukturen darstellen. Sie implementieren und richten eine Datenstruktur ein, damit Sie in Ihren Programmen problemlos mit ihnen arbeiten können, indem Sie Instanzen davon (d. H. Objekte) erstellen. 

1
Sumanth

Datenstrukturen (DS) sind eine abstrakte Art zu sagen, dass eine Struktur einige Daten enthält '. HashMap mit einigen Schlüsselwertpaaren ist eine Datenstruktur in Java. Assoziierte Arrays sind ähnlich in PHP usw. Objekte sind etwas niedriger als die Ebene DS. Ihre Hashmap ist eine Datenstruktur. Um nun eine Hashmap zu verwenden, erstellen Sie ein 'Objekt' davon und fügen dem Objekt mit der put-Methode Daten hinzu. Ich kann eine eigene Klasse Employee haben, die Daten hat und daher für mich ein DS ist. Um this DS zu verwenden, um einige Operationen auszuführen, z. B. um zu sehen, ob es sich bei dem Angestellten um einen männlichen oder weiblichen Kollegen handelt, brauche ich eine Instanz eines Angestellten und teste seine Gender-Eigenschaft.

Verwechseln Sie Objekte nicht mit Datenstrukturen.

0
Nazgul