Was bedeutet es für eine Datenstruktur, „aufdringlich“ zu sein?

120

Ich habe den Begriff aufdringlich gesehen, der zur Beschreibung von Datenstrukturen wie Listen und Stapeln verwendet wird, aber was bedeutet das?

Können Sie ein Codebeispiel für eine aufdringliche Datenstruktur geben und wie unterscheidet sie sich von einer nicht aufdringlichen?

Warum sollte es auch aufdringlich (oder nicht aufdringlich) sein? Was sind die Vorteile? Was sind die Nachteile?

Rüdiger
quelle

Antworten:

107

Eine aufdringliche Datenstruktur erfordert Hilfe von den Elementen, die gespeichert werden sollen, um sie zu speichern.

Lassen Sie mich das umformulieren. Wenn Sie etwas in diese Datenstruktur einfügen, wird diesem "Etwas" bewusst, dass es sich in irgendeiner Weise in dieser Datenstruktur befindet. Durch Hinzufügen des Elements zur Datenstruktur wird das Element geändert.

Sie können beispielsweise einen nicht aufdringlichen Binärbaum erstellen, in dem jeder Knoten einen Verweis auf den linken und rechten Unterbaum sowie einen Verweis auf den Elementwert dieses Knotens enthält.

Sie können auch eine aufdringliche erstellen, bei der die Verweise auf diese Unterbäume in den Wert selbst eingebettet sind.

Ein Beispiel für eine aufdringliche Datenstruktur wäre eine geordnete Liste von Elementen, die veränderlich sind. Wenn sich das Element ändert, muss die Liste neu angeordnet werden, sodass das Listenobjekt in die Privatsphäre der Elemente eingreifen muss, damit sie zusammenarbeiten können. dh. Das Element muss über die Liste, in der es sich befindet, Bescheid wissen und es über Änderungen informieren.

ORM-Systeme drehen sich normalerweise um aufdringliche Datenstrukturen, um die Iteration über große Listen von Objekten zu minimieren. Wenn Sie beispielsweise eine Liste aller Mitarbeiter in der Datenbank abrufen, dann den Namen eines dieser Mitarbeiter ändern und ihn wieder in der Datenbank speichern möchten, wird die aufdringliche Liste der Mitarbeiter angezeigt, wenn sich das Mitarbeiterobjekt aufgrund dessen geändert hat Objekt weiß, in welcher Liste es ist.

Eine nicht aufdringliche Liste würde nicht erzählt und müsste herausfinden, was sich geändert hat und wie es sich von selbst geändert hat.

Lasse V. Karlsen
quelle
8
Ich würde immer noch gerne ein Beispiel und die Vor- und Nachteile sehen, aber dies ist eine gute Einführung.
Rüdiger
Anstelle der Postleitzahl werde ich sagen, dass die STL nicht aufdringlich ist, während Boost.Intrusive (offensichtlich) aufdringlich ist.
Steinmetz
1
Aufdringliche Vorteile: Sie müssen Ihre Daten nicht in eine interne Struktur kopieren, sondern können unverändert verwendet werden. Nachteile: Sie müssen die Kapselung Ihrer Daten unterbrechen, um die Container zu unterstützen, in denen Ihre Daten gespeichert werden sollen. Es kann schwierig werden, wenn sich Ihre Daten in mehreren Containern befinden müssen. Nicht aufdringliche Container Vorteile: Bessere Kapselung, ohne dass Daten für Ihre Container geändert werden müssen. Nachteile: Erfordert eine Kopie Ihrer Daten in die interne Knotenstruktur.
Steinmetz
3
boost.org/doc/libs/1_45_0/doc/html/intrusive.html enthält Beispiele und eine gute Beschreibung der Vor- und Nachteile.
Tony Delroy
5
Tolle Erklärung mit Beispielen: boost.org/doc/libs/1_55_0/doc/html/intrusive/…
Paweł Szczur
22

In einem aufdringlichen Container sind die Daten selbst dafür verantwortlich, die erforderlichen Informationen für den Container zu speichern. Das bedeutet, dass einerseits der Datentyp abhängig von der Art der Speicherung spezialisiert werden muss, andererseits bedeutet dies, dass die Daten "wissen", wie sie gespeichert werden, und somit etwas besser optimiert werden können.

Nicht aufdringlich:

template<typename T>
class LinkedList
{
  struct ListItem
  {
    T Value;
    ListItem* Prev;
    ListItem* Next;
  };

  ListItem* FirstItem;
  ListItem* LastItem;

  [...]
  ListItem* append(T&& val)
  {
    LastItem = LastItem.Next = new ListItem{val, LastItem, nullptr};
  };
};

LinkedList<int> IntList;

Aufdringlich:

template<typename T>
class LinkedList
{
  T* FirstItem;
  T* LastItem;

  [...]
  T* append(T&& val)
  {
    T* newValue = new T(val);
    newValue.Next = nullptr;
    newValue.Prev = LastItem;
    LastItem.Next = newValue;
    LastItem = newValue;
  };
};

struct IntListItem
{
  int Value;
  IntListItem* Prev;
  IntListItem* Next;
};

LinkedList<IntListItem> IntList;

Persönlich bevorzuge ich aufdringliches Design wegen seiner Transparenz.

API-Beast
quelle
Diese letzte Zeile ist aufgrund der Verwendung des Wortes "transparent" merkwürdig, da es für das Objekt nicht transparent ist, sich in einem aufdringlichen Container zu befinden .
Schlitten
@ArtB Es ist klarer zu vermitteln, wie die Daten genau in der endgültigen Anwendung verwendet werden. Bei nicht aufdringlichen Daten müssen Sie normalerweise in die Container graben, während Sie aufdringliche Daten nur anhand der Datenstruktur sehen.
API-Beast
1
Nun, ich nehme an, jede Verwendung von "transparent" von transparent sollte in Bezug auf welche Perspektive qualifiziert werden. Nach meiner Erfahrung wird "transparent" häufig verwendet, um anzuzeigen, dass der Umgang mit den Daten für die Domäne unsichtbar ist (dh, dass die Domänenmodellierung rein ist). Wenn der Begriff in beide Richtungen verwendet wird, frage ich mich, ob er irgendeinen Wert hat.
Schlitten
2
@ ArtB Oh! Es gibt eine spezielle Bedeutung der Informatik für transparent! Transparent bedeutet für mich, dass Sie die Interna sehen können, z. B. "die Sicht nicht behindern", wie der Begriff in einem Nicht-CS-Kontext verwendet wird.
API-Beast