AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Objekt innerhalb Klasse nach außen hin "ReadOnly"
Thema durchsuchen
Ansicht
Themen-Optionen

Objekt innerhalb Klasse nach außen hin "ReadOnly"

Ein Thema von Rob09 · begonnen am 10. Apr 2011 · letzter Beitrag vom 11. Apr 2011
Antwort Antwort
Seite 1 von 2  1 2      
Rob09

Registriert seit: 14. Aug 2007
58 Beiträge
 
Delphi 6 Personal
 
#1

Objekt innerhalb Klasse nach außen hin "ReadOnly"

  Alt 10. Apr 2011, 22:43
Delphi-Version: 6
Hi!

Ich habe ein kleines Problem und würde mich sehr über etwas Hilfe freuen.

Es geht dabei um die wie folgt aufgebaute Klasse:
Code:
type
  TMyKlasse = class(TObject)
  private
    FUnterObjekt: TUnterKlasse;
    ...
  public
    ...
    property UnterObjekt: TUnterKlasse read FUnterObjekt;
  end;
So, nun mein Problem:

Die Klasse TUnterKlasse enthält properties, die man "im normalen Gebrauch" (d.h. wenn sie als "eigenständiges" Objekt instanziert wird) schreiben darf. Das muss für meine Zwecke so sein. In diesem Fall allerdings, in dem UnterObjekt eine property von TMyKlasse ist, hätte ich es gerne so, dass sich sämtliche properties von FUnterObjekt wie ReadOnly verhalten. Optimalerweise soll auch verhindert werden, dass man irgendwelche Methoden von FUnterObjekt aufrufen kann. D.h. man soll hier von FUnterObjekt eigentlich wirklich nur Eigenschaften auslesen dürfen, sonst nichts. Geht das irgendwie?

Beste Grüße!
Robert

PS (ganz andere Frage): Fallen constructor und destructor eigentlich auch unter den Oberbegriff "Methode"?
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#2

AW: Objekt innerhalb Klasse nach außen hin "ReadOnly"

  Alt 10. Apr 2011, 23:03
Ich glaube nicht, dass das geht, da du eigentlich nur einen Pointer auf ReadOnly gesetzt hast, denn die Property UnterObjekt enthält ja lediglich einen Zeiger auf die Klasse, die irgendwo im Speicher liegt.

Eine Idee für dein Konzept: Warum kapselst du das Objekt nicht vollständig und bietest nach außen nur Getter-Methoden (oder auch als Properties) an?
Delphi-Quellcode:
type
  TUnterKlasse = class(...)
  private
    ...
  public
    property A : String read FA write FA;
    property B : String read FB write FB;
    property C : String read FC write FC;
  end;

  TMyKlasse = class(TObject)
  private
    FUnterObjekt: TUnterKlasse;
    ...
  public
    ...
    //property UnterObjekt: TUnterKlasse read FUnterObjekt;

    // als public getter
    function GetUnterObjectA(): String;
    function GetUnterObjectB(): String;
    function GetUnterObjectC(): String;
    
   // oder als Properties, dann kannst du die Getter-Methoden
   // aber private setzen
   property UnterObjectA : String read GetUnterObjectA;
   property UnterObjectB : String read GetUnterObjectB;
   property UnterObjectC : String read GetUnterObjectC;
  end;
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Rob09

Registriert seit: 14. Aug 2007
58 Beiträge
 
Delphi 6 Personal
 
#3

AW: Objekt innerhalb Klasse nach außen hin "ReadOnly"

  Alt 10. Apr 2011, 23:26
Guter Denkanstoß!

Ich denke, ich werde eine THilfsKlasse einführen, die sämtliche Getter (bzw. ReadOnly-properties) und eine nicht auslesbare Referenz auf ein Objekt vom Typ TUnterKlasse (in diesem Fall FUnterObjekt) enthält. TMyKlasse bekommt dann ein FHilfsObjekt vom Typ THilfsKlasse spendiert und ich ändere die property UnterObjekt in FMyKlasse dahingehend, dass diese auf FHilfsObjekt verweist.

Ist zwar ein bisschen um die Ecke, aber sollte funktionieren...

Vielen Dank und Gruß!
Robert

Geändert von Rob09 (10. Apr 2011 um 23:29 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#4

AW: Objekt innerhalb Klasse nach außen hin "ReadOnly"

  Alt 10. Apr 2011, 23:33
Warum integrierst du es nicht direkt? Diese eine "Reader"-Klasse ist dann doch mehr oder weniger unnütz?
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Rob09

Registriert seit: 14. Aug 2007
58 Beiträge
 
Delphi 6 Personal
 
#5

AW: Objekt innerhalb Klasse nach außen hin "ReadOnly"

  Alt 10. Apr 2011, 23:35
Hmmm...

Wenn jetzt alerdings FUnterObjekt wiederum nicht nur Datentypen, sondern auch Objekte enthält, habe ich das gleiche Problem wieder - nur eine Ebene tiefer

nehme aber an, dass es prinzipiell keine Lösung gibt, die genau meinen Bedürfnissen entspricht... Oder?
  Mit Zitat antworten Zitat
Rob09

Registriert seit: 14. Aug 2007
58 Beiträge
 
Delphi 6 Personal
 
#6

AW: Objekt innerhalb Klasse nach außen hin "ReadOnly"

  Alt 10. Apr 2011, 23:37
Naja, falls ich weitere TMyKlasse2, TMyKlasse3, ... habe, die ebenfalls ein ReadOnly-Unterobjekt vom selben Typen haben, wäre die THilfsKlasse ja schon sinnvoll.
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#7

AW: Objekt innerhalb Klasse nach außen hin "ReadOnly"

  Alt 11. Apr 2011, 00:23
Hatte nicht vermutet, dass das Problem so weitläufig ist Von daher kann so eine Reader-Klasse durchaus ihren Sinn erfüllen. Zur Not würde ich an der Stelle evtl. noch über RTTI nachdenken.
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
schlecki

Registriert seit: 11. Apr 2005
Ort: Darmstadt
148 Beiträge
 
Delphi XE2 Enterprise
 
#8

AW: Objekt innerhalb Klasse nach außen hin "ReadOnly"

  Alt 11. Apr 2011, 00:37
was evtl auch noch eine Möglichkeit wäre, einfach ein Interface zu exportieren.

Hierbei kannst du genau angegeben, auf was zugreifbar ist.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#9

AW: Objekt innerhalb Klasse nach außen hin "ReadOnly"

  Alt 11. Apr 2011, 07:22
Oder eine weitere Klasse (quasi so wie beim Interface), welche nur die gewünschten Propertry und das eine Objekt enthält.
Im Private/Protected-Abschnitt dann noch öffentlich ein Property zum enthaltenen Objekt.

Wenn beide Klassen Die Kapsel-Klasse und deine Basisklasse in der selben Unit deklariert sind, dann kannstr du von deiner Klasse auch auf die privaten Sachen zugreifen und kommst so intern an alles ran. Von außen sieht aber jeder nur das ReadOnly-Zeugs.




Ist das TUnterKlasse von dir geschreiben?
Wenn ja, dann regel das über die Sichtbarkeiten und mach nur das Sichtbar, was auch sichtbar sein soll,
woei es auch so ginge, wie z.B. bei TEdit (für dich) und TCustomEdit (öffentlich).
$2B or not $2B
  Mit Zitat antworten Zitat
Rob09

Registriert seit: 14. Aug 2007
58 Beiträge
 
Delphi 6 Personal
 
#10

AW: Objekt innerhalb Klasse nach außen hin "ReadOnly"

  Alt 11. Apr 2011, 20:29
Zunächst mal vielen Dank an euch alle für die Hilfe!

Habe hier mal zwei mögliche Lösungen implementiert.

Dier erste benutzt ein "Kapsel-Objekt" (namens ExpKlasseRO) innerhalb der OberKlasse, auf das der Benutzer zugreifen darf. Dieses liest alle Eigenschaften vom eigentlichen UnterObjekt ohne Schreibzugriff, wobei der User das eigentliche UnterObjekt gar nicht sieht. Das ist die Lösung, die auf Vorschlag von s.h.a.r.k. entstanden ist. Bitte dabei um Entschuldigung, aber hab alle drei Klassen (TOberKlasse, TExpKlasse, TExpKlasseRO) in ne eigene unit gepackt:

PS: Die Namensgebung stimmt leider nicht mehr mit meiner ursprünglichen Frage überein. Was dort TMyKlasse war, ist jetzt TOberKlasse. Das einstige UnterObjekt vom Typ TUnterKlasse ist jetzt vom Typ TExpKlasse - was dem entpricht.

Delphi-Quellcode:
unit Unit1;

...

implementation

uses
  uTOberKlasse;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  x: TOberKlasse;
begin
  x := TOberKlasse.Create;

  {x.UnterObjektRO.EigenschaftRO := 10;} // geht natürlich nicht, soll ja auch ReadOnly sein

  Button1.Caption := IntToStr(x.UnterObjektRO.EigenschaftRO);
  FreeAndNil(x);
end;

end.
Delphi-Quellcode:
unit uTOberKlasse;

interface

uses
  uTExpKlasse, uTExpKlasseRO;

type

  TOberKlasse = class(TObject)
  private
    FUnterObjekt: TExpKlasse;
    FUnterObjektRO: TExpKlasseRO;
  public
    constructor Create;
    destructor Destroy; override;
    property UnterObjektRO: TExpKlasseRO read FUnterObjektRO;
  end;

implementation

uses
  SysUtils;

constructor TOberKlasse.Create;
begin
  inherited Create;
  FUnterObjekt := TExpKlasse.Create;
  FUnterObjektRO := TExpKlasseRO.Create(FUnterObjekt);
end;

destructor TOberKlasse.Destroy;
begin
  FreeAndNil(FUnterObjektRO);
  FreeAndNil(FUnterObjekt);
  inherited Destroy;
end;

end.
Delphi-Quellcode:
unit uTExpKlasse;

interface

type

  TExpKlasse = class(TObject)
  private
    FEigenschaft: Integer;
    procedure SetEigenschaft(AValue: Integer);
    function GetEigenschaft: Integer;
  public
    property Eigenschaft: Integer read GetEigenschaft write SetEigenschaft;
  end;

implementation

procedure TExpKlasse.SetEigenschaft(AValue: Integer);
begin
  FEigenschaft := AValue;
end;

function TExpKlasse.GetEigenschaft: Integer;
begin
  Result := FEigenschaft;
end;

end.
Delphi-Quellcode:
unit uTExpKlasseRO;

interface

uses
  uTExpKlasse;

type

  TExpKlasseRO = class(TObject)
  private
    FReferenzObjekt: TExpKlasse;
    function GetEigenschaftRO: Integer;
  public
    constructor Create(AReferenzObjekt: TExpKlasse);
    property EigenschaftRO: Integer read GetEigenschaftRO;
  end;

implementation

constructor TExpKlasseRO.Create(AReferenzObjekt: TExpKlasse);
begin
  inherited Create;
  FReferenzObjekt := AReferenzObjekt;
end;

function TExpKlasseRO.GetEigenschaftRO: Integer;
begin
  Result := FReferenzObjekt.Eigenschaft;
end;

end.


Die zweite Lösung ist die mit dem Interface, auf Vorschlag von schlecki.

Delphi-Quellcode:
unit Unit1;

...

implementation

uses
  uTOberKlasse;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  x: TOberKlasse;
begin
  x := TOberKlasse.Create;

  {x.UnterObjektRO.Eigenschaft := 10;} // geht natürlich NICHT, weil bei UnterObjektRO vom Typ IExpInterface ist .Eigenschaft ReadOnly

  Button1.Caption := IntToStr(x.UnterObjektRO.Eigenschaft);
  FreeAndNil(x);
end;

end.
Delphi-Quellcode:
unit uTOberKlasse;

interface

uses
  uTExpKlasse, uIExpInterface;

type

  TOberKlasse = class(TObject)
  private
    FUnterObjekt: TExpKlasse;
    FInterfaceUnterObjekt: IExpInterface;
  public
    constructor Create;
    destructor Destroy; override;
    property UnterObjektRO: IExpInterface read FInterfaceUnterObjekt;
  end;

implementation

uses
  SysUtils;

constructor TOberKlasse.Create;
begin
  inherited Create;
  FUnterObjekt := TExpKlasse.Create;
  FInterfaceUnterObjekt := FUnterObjekt;
end;

destructor TOberKlasse.Destroy;
begin

  // ACHTUNG!

  // entweder dies:
  FInterfaceUnterObjekt := nil;
  // ODER dies:
  {FreeAndNil(FUnterObjekt);}

  // siehe dazu z.B. http://development.mwcs.de/tutinterfaces.html
  // PS: Es entsteht KEIN Speicherleck!

  inherited Destroy;
end;

end.
Delphi-Quellcode:
unit uIExpInterface;

interface

type

  IExpInterface = interface(IInterface)
  ['{5DD93564-1E6D-4D23-9EEE-B6E232CF4D9F}']
    function GetEigenschaft: Integer;
    property Eigenschaft: Integer read GetEigenschaft;
  end;

implementation

end.
Delphi-Quellcode:
unit uTExpKlasse;

interface

uses
  uIExpInterface;

type

  TExpKlasse = class(TInterfacedObject, IExpInterface)
  private
    FEigenschaft: Integer;
    procedure SetEigenschaft(AValue: Integer);
    function GetEigenschaft: Integer;
  public
    property Eigenschaft: Integer read GetEigenschaft write SetEigenschaft;
  end;

implementation

procedure TExpKlasse.SetEigenschaft(AValue: Integer);
begin
  FEigenschaft := AValue;
end;

function TExpKlasse.GetEigenschaft: Integer;
begin
  Result := FEigenschaft;
end;

end.


In jedem Fall ist es der OberKlasse möglich, direkt auf UnterObjekt zuzugreifen und alle beliebigen Schreiboperationen durchzuführen, während der Benutzer, der ein Objekt vom Typ TOberKlasse verwendet, nur die gewünschten Eigenschaften von UnterObjekt innerhalb des OberObjekt auslesen kann, ohne Schreibzugriff. Die erste Variante ist auch geeignet, wenn es sich bei UnterKlasse um eine Klasse handelt, die man nicht selbst implementiert hat (vgl. Anmerkung von himitsu).

Hoffe, das hilft auch anderen weiter. Weitere Optimierungsvorschläge sind gerne erwünscht

Beste Grüße!
Robert

Geändert von Rob09 (12. Apr 2011 um 18:00 Uhr) Grund: Jetzt erst die [DELPHI]-Umgebung entdeckt ;-)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:40 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