Einzelnen Beitrag anzeigen

Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#5

Re: Werteübergabe zwischen Klassen in verschiedenen Units

  Alt 18. Jan 2006, 09:49
Zitat von Kroko1999:
ich glaube, die Klasse die die Daten hält sollte dies auch verarbeiten oder ?(OOP)!
Äh, lustige Idee, wie kommst du denn darauf? Nehmen wir mal ein Integer, hält auch ein Datum (auch ohne OOP, wer auf 'ne Klasse besteht baut sich halt einen Wrapper). Ok, wird nur von der Unit in der Integer definiert ist mit dem gearbeitet? Wohl kaum.

Was OOP angeht, so wird eine Klasse immer so aufgebaut, dass sie nach aussen wohl definierte Schnittstellen hat. Man überlegt sich in einem sehr abstrakten Modell, welche Klassen wie miteinander interagieren müssen.
Es gibt dabei allerdings kein richtig oder falsch, es variiert stark mit dem Betrachter und Problem, wie die Klassenstruktur aussieht.
Das ist auch erstmal alles was man tun sollte, man überlegt sich nur, was von welcher Klasse auch von aussen Sichtbar sein muss. Es geht hier auch wirklich nur um Methoden und Properties (Variablen sollten nie direkt sichtbar sein). Natürlich weiß man was eine Methode leisten soll, aber wie sie das macht, gehört noch nicht in das Design. Die Überlegung ist nur, was muss die Methode kennen / als Parameter bekommen.

Daraus kann man dann leicht abstrakte Klassen oder Interfaces erstellen. Von diesen leitet man dann etwas Konkretes ab (implementiert Interfaces). Damit hat man auch maximale Wiederverwendbarkeit, da man nur die konkrete Instanz tauschen muss. Aber das ist ein anderes Thema, findet ihr bestimmt ne Menge in der DP zu.

Zu dem hier geschilderten Problem, es hat denke ich weniger etwas mit OOP zu tun. Es geht nur um etwas mehr Überblick. Es wird sicherlich ein Hauptklasse geben, in der die Instanzen der Daten erzeugt werden. Ok, moment, ich führ einfach mal der Übersicht halber ein paar neue Namen ein. Klasse 1, 2 und 3 ist nicht gerade das wahre (sorry).
Also, sagen wir, wir haben eine Klasse TDaten. Diese bietet die Möglichkeit Daten zu speichern und die auch wieder auszugeben.
Dann haben wir eine Klasse TVearbeitung. Diese kennt die Klasse TDaten und kann diese Daten verarbeiten.
Als letztes bleibt eine Klasse TVerwaltung. Diese kennt alle Möglichkeiten der verarbeitung und die kennt auch alle Daten.

Jetzt gibt es mehrere Möglichkeiten wie diese Klassen interagieren könnten. Wie vielleicht schon gesehen wurde, habe ich hier eine andere Sichtweise genommen. Die Klassennamen sind nicht ganz ohne Bedacht gewählt, denn eure Klassenstruktur sieht sicherlich noch häufiger so aus. Man hat eine Zentrale Verwaltung, die muss (fast) alles kennen. Man hat einen Datentypen (analog für mehrere, von dem jeder einzeln betrachtet wird). Dieser Datentyp muss in der Verwaltung bekannt sein, da diese ihn verwaltet. Aber dieser Datentyp muss nicht wissen wie er verwaltet wird.
Dann bleibt noch die Verarbeitung. Diese muss wissen was für einen Datentypen sie bekommt, denn sie arbeitet auf diesem Datentypen. Der Datentyp muss aber nichts von der Verarbeitung wissen. Damit kann man auch ganz verschiedene Verarbeitungen für einen Datentypen entwickeln.
Die Verwaltung kennt wiederum die Verarbeitungsmöglichkeiten, aber auch hier ist die andere Richtung nicht nötig.

Nochmal zusammengefasst:
  • Datentyp : Muss ein Datum speichern und zurückgeben können
    [*}Verarbeitung : Bekommt etwas vom Typ Datentyp, verarbeitet es
  • Verwaltung : Erzeugt Instanzen vom Datentyp und lässt sie durch die Verarbeitung verarbeiten

Ist kein schönes oder Vollständiges Modell, aber ein einfaches. Natürlich könnte auch die Verarbeitung Instanzen erzeugen,...

Hier kennt jeder Punkt immer nur die über ihm Liegenden und das reicht auch.
Damit solltest du alles haben was du brauchst, noch mal als Beispiel:

Delphi-Quellcode:
// Unit 1
type
  TDatentyp = class(TObject)
    private
      // Variablen können immer privat sein
      FValue : Integer;
    protected
      function getValue : Integer;
      procedure setValue(const Value : Integer);
    public
      property Value read getValue write setValue;
  end;

// getValue und setValue dürfte klar sein
Delphi-Quellcode:
// Unit 2
// uses Unit 1;
type
  TVerarbeitung = class(TObject)
    public
      procedure doFoo(const Data : TDatenTyp);
  end;

procedure TVerarbeitung.doFoo(const Data : TDatenTyp);
begin
  // verdoppelt den in Data gespeicherten Wert
  if assigned(Data) then
    begin
      Data.Value := Data.Value * 2;
    end;
end;
Delphi-Quellcode:
// Unit 3
// uses Unit 1, Unit 2;
type
  TVerwaltung = class(TObject)
    private
      Datum : TDatenTyp;
      Verarbeitung : TVerarbeitung;
    protected
    public
      constructor create;
      destructor destroy; override;
      procedure setDatum(const Value : Integer);
      procedure doubleValue;
  end;

constructor TVerwaltung.create;
begin
  self.Datum := TDatenTyp.Create;
  self.Verarbeitung := TVerarbeitung.Create;
end;

destructor TVerwaltung.destroy;
begin
  self.Datum.Free;
  self.Verarbeitung.Free;
end;

procedure TVerwaltung.setDatum(const Value : Integer);
begin
  self.Datum.Value := Value;
end;

procedure TVerwaltung.doubleValue;
begin
  Verarbeitung.doFoo(self.Datum);
end;
Ja, auch hier gilt, ist kein schönes Beispiel, aber ich hoffe es macht die herangehensweise klarer. Wenn Verarbeitung deiner Klasse 3 entspricht und Verwaltung der Klasse 1, dann muss 3 die 1 nicht mehr kennen. 3 Bekommt nur irgendwas vom Typ Klasse 2 und arbeitet damit. Wen dieser Verarbeitete Wert interessiert und wo die Instanz von Klasse 2 herkam, dass alles muss Klasse 3 nicht wissen. Es muss nur ein Parameter vom richtigen Typen übergeben werden, der ist dann natürlich bekannt.
Das ganze sieht auch rein imperativ nicht anders aus.
Es hat also nicht wirklich etwas mit OOP zu tun. Aber andererseits ist es insbesondere (auch) in der OOP eine Vorschrift, dass niemand mehr sieht als er muss. Keine Sorge, gutes Design der Klassen (oder Programme) bringt einem die Erfahrung. Designfehler passieren jedem mal. Sie kosten nur unterschiedlich viel. Je früher du sauber planst, desto geringer die kosten (am Anfang/ privat nur Zeit, später recht viel Geld).

Gruß Der Unwissende
  Mit Zitat antworten Zitat