Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   OOP - Zugriff von Objekten untereinander (https://www.delphipraxis.net/161119-oop-zugriff-von-objekten-untereinander.html)

Viktorii 17. Jun 2011 13:12

OOP - Zugriff von Objekten untereinander
 
Moin.

Hab da mal ne konzeptionelle Frage. Um ein möglichst einfaches Beispiel zu nennen sagen wir mal ich habe die Objekte ObjectA, ObjectB und ObjectC. ObjectC ist ein Member von ObjectB und ObjectB ist ein Member von ObjectA.
Also so (ohne die restlichen Memberfunktionen):
Delphi-Quellcode:
type
  TMyClassA = class(TObject)
  private
    ObjectB: TClassB;
  public

  end;


  TClassB = class(TObject)
  private
    ObjectC: TClassC;
  public

  end;


  TClassC = class(TObject)
  private

  public

  end;
Wenn nun aber ObjectA und ObjectC miteinander kommunizieren sollen (also ObjectA ruft Memberfunktionen von ObjectC auf) muss ich ja für jede Meberfunktion in ObjectB eine 'Durchreichfunktion' schreiben.

Das kann im wahren Leben sehr viel und unübersichtlich werden.

Eine Lösung wäre ObjectC in ObjectB pulic zu setzen. Dann könnte ObjectA direkt auf ObjectC zugreifen. Aber man soll Felder ja nie pulbic machen.

Wie löst man das am elegantesten?

CCRDude 17. Jun 2011 13:48

AW: OOP - Zugriff von Objekten untereinander
 
Lassen wir mal die Diskussion über Sinn und Unsinn dieser Querzugriffe beseite, empfehle ich Dir mal die verschiedenen Sichtbarkeiten genauer nachzulesen :)

private, protected ...
Zitat:

In general, most data and methods internal to a class should be defined in a Protected section. This gives subclasses often useful access to these. Only use Private when you are sure that you want to keep stuff entirely local to the current class/unit.
Geht also auch ohne public, aber wie Du schon sagst, sollte man nicht so unbedingt, überlege vielleicht mal, ob Du Deine Klassen anders definieren kannst, so daß sie weniger Abhängigkeiten voneinander haben.

BUG 17. Jun 2011 13:52

AW: OOP - Zugriff von Objekten untereinander
 
Zitat:

Zitat von Viktorii (Beitrag 1107001)
Wenn nun aber ObjectA und ObjectC miteinander kommunizieren sollen (also ObjectA ruft Memberfunktionen von ObjectC auf) muss ich ja für jede Meberfunktion in ObjectB eine 'Durchreichfunktion' schreiben.

Wenn A direkt mit C kommunizieren soll, sollte A vielleicht C kennen.
Dafür könntest du in B einen Getter schreiben oder aus B heraus eine Funktion von A mit Argument C aufrufen.

Wenn du in geben willst/kannst/darfst, wäre etwas Kontext nicht schlecht: Was sind A, B und C für Objekte?

stahli 17. Jun 2011 13:59

AW: OOP - Zugriff von Objekten untereinander
 
Man kann (je nach den gegebenen Umständen) ein privates Feld auch als Eigenschaft zugänglich machen (property).

So könntest Du ein Objekt als solches als read only öffentlich machen.

Delphi-Quellcode:
type
  TMyClassA = class(TObject)
  private
    FObjectB: TClassB;
  public
    property ObjectB: TClassB read FObjectB;
  end;

Ein Unterobjekt öffentlich zu machen, muss ja nicht verkehrt sein.
Im Beispiel könnte man kein anderes Objekt zuweisen.

Schreib evtl. mal mehr zu Deinem Problem...


EDIT: TEdit.Font ist ja auch nichts anderes.

DeddyH 17. Jun 2011 14:01

AW: OOP - Zugriff von Objekten untereinander
 
Zitat:

Zitat von stahli (Beitrag 1107008)
Im Beispiel könnte man kein anderes Objekt zuweisen.

Aber man könnte es freigeben. Das kann natürlich gewollt sein, trotzdem sollte man diesen Umstand im Hinterkopf behalten.

mquadrat 17. Jun 2011 14:17

AW: OOP - Zugriff von Objekten untereinander
 
Nach Meinung einer der OOP-Gurus wäre aber genau das, was du beschrieben hast die Lösung. Da A C nicht kennt, darf A C nicht vertrauen und ergo dort auch nichts aufrufen.

BUG 17. Jun 2011 14:25

AW: OOP - Zugriff von Objekten untereinander
 
Zitat:

Zitat von mquadrat (Beitrag 1107010)
Da A C nicht kennt, darf A C nicht vertrauen und ergo dort auch nichts aufrufen.

Was aber die Frage aufwirft, warum A Methoden von C benutzen soll und ob die fraglichen Stellen in A dann nicht eher in eine öffentliche Methode von B gehören.

stahli 17. Jun 2011 14:34

AW: OOP - Zugriff von Objekten untereinander
 
@mquadrat

Wenn aber noch dutzende andere Klassen ein ObjectC verwenden, dann wird das Ganze recht aufwendig.

Man kann die durchgereichten Methoden natürlioch in eine Include-Datei legen und diese in allen Klassen verwenden (vorausgesetzt, die Variable heißt auch überall "ObjectC"). So spart man sich viel Schreiberei, aber die Methoden "müllen" natürlich dann die Memberliste der Klassen zu (tauchen immer in der Codevervollständigung auf).

Wenn es keinen zwingenden Grund für solch eine Durchreichung gibt (z.B. wenn ausdrücklich nur ein paar ausgewählte ObjectC-Methoden verfügbar sein sollen), würde ich es als Eigenschaft öffentlich machen.

@BUG

Nimm doch z.B. mal Edit.Font. Da ist doch Font auch komplett zugänglich.
Wozu sollte man hier Edit.FontSize einführen? Ich würde dies nur machen, wenn es wirklich zwingende Gründe dafür gibt.

mquadrat 17. Jun 2011 15:48

AW: OOP - Zugriff von Objekten untereinander
 
@stahli

Sehe ich ähnlich. Zumal das Risiko sinkt, wenn die Klassen vom gleichen Autor kommen ;) Ich würde mich da auch eher für die Bequemlichkeit als für die reine Lehre entscheiden.

Stevie 17. Jun 2011 15:55

AW: OOP - Zugriff von Objekten untereinander
 
Ist etwas schwierig, das so global ohne konkretes Fallbeispiel zu beurteilen. Wie schon das Beispiel von Stahli zeigt, gibt es durchaus plausible Gründe gibt, das Law of demeter nicht zu erzwingen. Andererseits ergibt sich daraus eine Abhängigkeit, die du eventuell gerade dadurch, dass A nicht C kennt, vermeiden willst (denn wenn du in A dann Self.B.C aufrufst, hast du nix gewonnen). Somit wäre zu überlegen, was genau will denn A in deinem Fall von C? Wäre es nicht besser, eine Methode auf B aufzurufen, die dann weiter an C delegiert?

Beispiel, was für das LoD immer wieder herangezogen wird, ist das paper boy example.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:10 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz