AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Zwei Klassen möglichst "OOP" kommunuzieren lassen
Thema durchsuchen
Ansicht
Themen-Optionen

Zwei Klassen möglichst "OOP" kommunuzieren lassen

Ein Thema von xZise · begonnen am 4. Sep 2006 · letzter Beitrag vom 6. Sep 2006
Antwort Antwort
Seite 2 von 3     12 3      
Der_Unwissende

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

Re: Zwei Klassen möglichst "OOP" kommunuzieren las

  Alt 5. Sep 2006, 17:41
Zitat von xZise:
Oh man... das es SOOOO schwer ist, hab ich nicht gedacht
Also ich habe es so programmiert:
Code:
 
=============> LangMain (Allgemeine Prozeduren)
LangLabel
          <=== LangProcs (Prozeduren, die Daten von den Komponenten benötigen
Das Problem ist ja (eigentlich wäre es schöner LangProcs und LangMain in einer zu Haben), dass LangProcs Informationen der Komponenten brauch. Und die Komponenten müssen auf Allgemiene Prozeduren zurgreifen (oder es wäre effektiver), da dort Code für jede Komponente steht.
Verstehe ich nicht wirklich, muss ich mal sagen.

Zitat von shmia:
Es gäbe da noch eine andere interessante Technik.
Alle Komponenten haben die virtuelle Methode Notification.
Man kann diese Methode überschreiben und könnte automatisch Verbindungen zur MasterKomponente (LangMain) herstellen und trennen.
Hm, woher wissesn die denn wer die Master-Komponente ist? Das bekanntmachen ist eine Art registrieren und läuft letztlich doch auf Observer hinaus. Ausserdem muss die Masterkomponente alle "Kinder" benachrichtigen, nicht umgekehrt (oder habe ich da etwas falsch verstanden?) Also der Fall tritt ja letztlich immer auf. Verändert man etwas an der Masterkomponente sollen diese Änderungen auch an allen Kindern stattfinden. Umgekehrt geht nicht (alle Kidner verändern), bleibt also noch ein Kind verändern, allen Bescheid geben, was dann aber auch ein Kind -> Master -> an alle sein könnte.
Damit ein Master also alle Kinder kennt müssen diese sich beim Master registrieren (=> Observerpattern gut geeignet). Natürlich kann man noch etwas drum rum bauen (z.B. eine Fabrik), die die Registrierung automatisch übernimmt.
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#12

Re: Zwei Klassen möglichst "OOP" kommunuzieren las

  Alt 5. Sep 2006, 18:12
Zitat von Der_Unwissende:
Hm, woher wissesn die denn wer die Master-Komponente ist?
Das könnte man über den Klassennamen ermitteln.
Aber ich habe noch etwas experimentiert: Notification() wird schon von der VCL aufgerufen,
bevor der Konstruktor komplett abgearbeitet ist.
Das scheint mir dann doch nicht so günstig zu sein.
Andreas
  Mit Zitat antworten Zitat
Benutzerbild von xZise
xZise

Registriert seit: 3. Mär 2006
Ort: Waldbronn
4.303 Beiträge
 
Delphi 2009 Professional
 
#13

Re: Zwei Klassen möglichst "OOP" kommunuzieren las

  Alt 5. Sep 2006, 18:39
Das große Problem ist:
Die Komponenten (=Edit, Label nicht MAIN!) haben alle ein paar Funktionen gemeinsam... Deshalb habe ich sie in Main ausgelagert. Nun habe ich auch eine Methode geschrieben, die alle "Lang"-Komponenten auf der Form ansprechen soll. Und diese habe ich logischerweise in die Main geschrieben, aber ich werde wohl das alles umdenken (müssen)... Weil wie es bisher ist, ist es nicht schön und umständlich.
Fabian
Eigentlich hat MS Windows ab Vista den Hang zur Selbstzerstörung abgewöhnt – mkinzler
  Mit Zitat antworten Zitat
Benutzerbild von DGL-luke
DGL-luke

Registriert seit: 1. Apr 2005
Ort: Bad Tölz
4.149 Beiträge
 
Delphi 2006 Professional
 
#14

Re: Zwei Klassen möglichst "OOP" kommunuzieren las

  Alt 5. Sep 2006, 19:23
implementiere diese Sachen doch in der basisklasse?!

Delphi-Quellcode:
type
  //TOnLanguageChange = procedure(NewString: string) of object;

  TLangSensObservable = class; //forward
  TLangSensComp = class(TComponent) //könnte natürlich auch ein Interface sein! Würde die mehrfachvererbung möglich machen...
    private
      FIdent: Integer;
    public
      procedure RegisterToObservable(Observable: TLangSensObservable); virtual; //ruft nur RegisterObserver auf...
      procedure UpdateLanguage; virtual;
      procedure OnLanguageChange(NewString: string); virtual;
    published
      property Identifier: Integer read FIdent write FIdent;
  end;

  TLangSensObservable = class(TObject);
    private
      FObservers: TObjectList;
    public
      procedure RegisterObserver(Observer: TLangSensComponent);
      function GetCurrentString(Ident: Integer): string; overload;
      procedure SetLanguage(lang: string); //geht über string, geht natürlich ebenso über index... ka wie du deine Daten speichern willst...
  end;
So würds ich machen.
Wenn du in mehreren Klassen, die von einer Basisklasse abgeleitet sind, gleichen Code schreiben musst, ist das auf jeden Fall falsch bzw. ein designfehler!
Wenn du aber "bequem" von VCL-Kompos ableiten willst, ist es ideal, mit Interfaces zu arbeiten. Du kannst zwar nicht von TInterfacedObject ableiten (musst also die Referenzzählung selber einbauen, denke ich ), aber das ist trotzdem ein idealer Einsatzort für Interfaces.
Lukas Erlacher
Suche Grafiktablett. Spenden/Gebrauchtangebote willkommen.
Gotteskrieger gesucht!
For it is the chief characteristic of the religion of science that it works. - Isaac Asimov, Foundation I, Buch 1
  Mit Zitat antworten Zitat
Benutzerbild von xZise
xZise

Registriert seit: 3. Mär 2006
Ort: Waldbronn
4.303 Beiträge
 
Delphi 2009 Professional
 
#15

Re: Zwei Klassen möglichst "OOP" kommunuzieren las

  Alt 5. Sep 2006, 20:18
Hab ich nur vergessen was mit Interface gemeint ist, oder hab ich das tatsächlich noch nie gehört? (Erkläre das mal bitte kurz)

So: Nun denke ich ist es langsam (*räusper*) an der Zeit mal euch das Grundgerüst zu geben:
- Es gibt "Komponentenunit", die z.Zt. LangLabel und LangEdit sind (ich wollte erstmal die Kinderkrankheiten auskurieren)
(Die Units sind von TLabel/TEdit abgeleitet)
- Es gibt eine Klasse in der die Funktion ist, die alle benötigen (sozusagen deie Übersetzungsfunktion)
- Es gibt eine Prozedur die auf alle Komponentenunits zugreifen muss

Es sind alles verschiedene "*.pas"!

Jetzt wüsste ich gerne: Was muss ich bei den Klassen dazuschreiben?

Muss ich z.B. bei LangMain das hinzufügen:
Delphi-Quellcode:
type
  TLangSensObservable = class; //forward
  TLangSensComp = class(TComponent) //könnte natürlich auch ein Interface sein! Würde die mehrfachvererbung möglich machen...
    private
      FIdent: Integer;
    public
      procedure RegisterToObservable(Observable: TLangSensObservable); virtual; //ruft nur RegisterObserver auf...
      procedure UpdateLanguage; virtual;
      procedure OnLanguageChange(NewString: string); virtual;
    published
      property Identifier: Integer read FIdent write FIdent;
  end;

  TLangSensObservable = class(TObject);
    private
      FObservers: TObjectList;
    public
      procedure RegisterObserver(Observer: TLangSensComponent);
      function GetCurrentString(Ident: Integer): string; overload;
      procedure SetLanguage(lang: string);
  end;

  // Me/ain Code
  TLangMain = class(TObject);
    {...}
  end;
Eins möchte ich hier noch loswerden: Ich komme mit euren Antworten irgendwie leider nicht weiter Deshalb kann es sein, dass ich schon beantwortete Fragen nochmal stelle... Sry
Fabian
Eigentlich hat MS Windows ab Vista den Hang zur Selbstzerstörung abgewöhnt – mkinzler
  Mit Zitat antworten Zitat
Benutzerbild von DGL-luke
DGL-luke

Registriert seit: 1. Apr 2005
Ort: Bad Tölz
4.149 Beiträge
 
Delphi 2006 Professional
 
#16

Re: Zwei Klassen möglichst "OOP" kommunuzieren las

  Alt 6. Sep 2006, 18:48
OK, is kein problem.

Interface:
Die einzige Möglichkeit zur Mehrfachvererbung in Delphi. Folgender Code:
Delphi-Quellcode:
type
  ILangObserver = interface(IInterface)
    procedure NotifyLanguageChanged(NewString: string);
    function GetStringId: Integer;
  end;
Du hast damit sozusagen eine Kompatibilitätsvorraussetzung geaschaffen. Alle ILangObserver implementierenden Klassen müssen die in der ILangObserver-Deklaration vereinbarten Methoden bieten:

Delphi-Quellcode:
type
  TLanglabel = class(TLabel, ILangObserver)
  public
    {ILangObserver}
    procedure NotifyLanguageChanged(NewString: string);
    function GetStringId: Integer;
    {IInterface}
    ... //weiss ich jetzt grad nicht was da noch hinmuss
  end;
  TLangPanel = class(TPanel, ILangObserver)
  public
    {ILangObserver}
    procedure NotifyLanguageChanged(NewString: string);
    function GetStringId: Integer;
    {IInterface}
    ... //weiss ich jetzt grad nicht was da noch hinmuss
  end;
  TLangGroupBox = class(TGroupBox, ILangObserver)
  public
    {ILangObserver}
    procedure NotifyLanguageChanged(NewString: string);
    function GetStringId: Integer;
    {IInterface}
    ... //weiss ich jetzt grad nicht was da noch hinmuss
  end;
Du musst nun diese Methoden (ja, das ist ein wenig suboptimal) in jeder Klasse implementieren.

Du kannst deine TLang*-Kompos jetzt (wie bei einer Elternklasse) auf das ILangObserver-Interface reduzieren:

Delphi-Quellcode:
  TLangObservable = class(TObject)
  public
    procedure Register(Observer: ILangObserver);
  end;
Du kannst die Interfaces in dieser Methode dann in eine Liste schreiben (das ist nicht ganz so... unenmpfindlich)und benachrichtigen:

Delphi-Quellcode:
procedure TLangObservable.LanguageChange(Language: string);
var Observer: ILangObserver;
begin
  LanguageSet(Language);

  for i := 0 to List.Count-1 do
    begin
      Observer := List[i] as ILangObserver;
      Observer.NotifyLanguageChange(GetLangstring(Observer.GetStringId));
    end;
end;
Das als kurze Einführung in die Vorteile von Interfaces. Du hast auch noch eine Referenzzählung, das zur Vollständigkeit, und das macht das hantieren damit ein wenig gefährlich, weil dir eventuell irgendwo instanzen übrigbleiben, und du bei der herumreichung von zeigern viel falsch machen kannst.
Dazu solltest du dich allerdings einlesen.

Du kommst mit unseren Antworten nicht klar? Naja, ist ja auch alles hochprozentiges OOP
Lukas Erlacher
Suche Grafiktablett. Spenden/Gebrauchtangebote willkommen.
Gotteskrieger gesucht!
For it is the chief characteristic of the religion of science that it works. - Isaac Asimov, Foundation I, Buch 1
  Mit Zitat antworten Zitat
Benutzerbild von xZise
xZise

Registriert seit: 3. Mär 2006
Ort: Waldbronn
4.303 Beiträge
 
Delphi 2009 Professional
 
#17

Re: Zwei Klassen möglichst "OOP" kommunuzieren las

  Alt 6. Sep 2006, 19:19
Cool! Danke, hat mir echt weitergeholfen! Noch ein paar Fragen bleiben noch:
- Muss ich den Code überalls schreiben, oder reicht der Kopf?
- Was ist mit GetStringId? Ist das wichtig/Notwendig?
- Kennen die Komponentenklassen die Interasceklasse?
- Was hat es mit dem Register auf sich?
Fabian
Eigentlich hat MS Windows ab Vista den Hang zur Selbstzerstörung abgewöhnt – mkinzler
  Mit Zitat antworten Zitat
Benutzerbild von DGL-luke
DGL-luke

Registriert seit: 1. Apr 2005
Ort: Bad Tölz
4.149 Beiträge
 
Delphi 2006 Professional
 
#18

Re: Zwei Klassen möglichst "OOP" kommunuzieren las

  Alt 6. Sep 2006, 19:31
1. du hast in interfaces leider absolut keine möglichkeit, code zu hinterlegen. das ist auch nciht der sinn von interfaces, sowas wäre sainn von echter mehrfachvererbung also ja, du musst den code überall neu schreiben.
2. klar ist das wichtig. damit weiss der sprachen-"server", welchen string er dir jeweils liefern soll. nehmen wir einmal an, wir haben es in XML:

XML-Code:
<language name="de/de">
  <string id="0">%s</string>
  <string id="1">Hallo, benutzer!</string>
</language>
<language name="en/us">
  <string id="0">%s</string>
  <string id="1">Hello, user!</string>
</language>
dann musst du, um einen string zu bekommen, Sprache und id haben.
3. Wie kennen? Die Implementation eines Interfaces bedeutet, da ist ein Objekt, das verfügt über bestimmte Eigenschaften, und das absolut unabhängig von allen anderen Charakteristika der Klasse. Sozusagen ein black-box-modell: Du hast einen schwarzen Kasten, von dem du nicht weisst,was er macht, aber du hast bestimmte Schnittstellen (man übersetze mal das wort "interface" ), von denen du genau weisst, wie sie funktionieren. In diesem schwarzen Kasten kann alles möglcihe drinsein, aber das ist dir völlig egal, wichtig ist (auf einer Seite) nur die Schnittstelle.
4. Damit registriert sich eine Komponente beim "Server", um beim Wechseln der Sprache auch den neuen string zu bekommen(Observer-Pattern! Bei Bedarf noch mal weiter oben nachlesen ). Es wäre übrigens auch denkbar, dort bereits die string-id zu übergeben, damit die nicht immer nochmal gequeriet... äh... abgefragt werden muss.
Lukas Erlacher
Suche Grafiktablett. Spenden/Gebrauchtangebote willkommen.
Gotteskrieger gesucht!
For it is the chief characteristic of the religion of science that it works. - Isaac Asimov, Foundation I, Buch 1
  Mit Zitat antworten Zitat
Benutzerbild von xZise
xZise

Registriert seit: 3. Mär 2006
Ort: Waldbronn
4.303 Beiträge
 
Delphi 2009 Professional
 
#19

Re: Zwei Klassen möglichst "OOP" kommunuzieren las

  Alt 6. Sep 2006, 20:27
Zitat von DGL-luke:
1. du hast in interfaces leider absolut keine möglichkeit, code zu hinterlegen. das ist auch nciht der sinn von interfaces, sowas wäre sainn von echter mehrfachvererbung also ja, du musst den code überall neu schreiben.
Dann verstehe ich nicht den Sinn

Zitat von DGL-luke:
2. klar ist das wichtig. damit weiss der sprachen-"server", welchen string er dir jeweils liefern soll. nehmen wir einmal an, wir haben es in XML:

XML-Code:
<language name="de/de">
  <string id="0">%s</string>
  <string id="1">Hallo, benutzer!</string>
</language>
<language name="en/us">
  <string id="0">%s</string>
  <string id="1">Hello, user!</string>
</language>
dann musst du, um einen string zu bekommen, Sprache und id haben.
Ist es denn Pflicht für ein Interface (das wollte ich wissen)

Zitat von DGL-luke:
3. Wie kennen? Die Implementation eines Interfaces bedeutet, da ist ein Objekt, das verfügt über bestimmte Eigenschaften, und das absolut unabhängig von allen anderen Charakteristika der Klasse. Sozusagen ein black-box-modell: Du hast einen schwarzen Kasten, von dem du nicht weisst,was er macht, aber du hast bestimmte Schnittstellen (man übersetze mal das wort "interface" ), von denen du genau weisst, wie sie funktionieren. In diesem schwarzen Kasten kann alles möglcihe drinsein, aber das ist dir völlig egal, wichtig ist (auf einer Seite) nur die Schnittstelle.
Muss ich den bei LangLabel (z.B.) das Interface importen (=uses)?

Zitat von DGL-luke:
4. Damit registriert sich eine Komponente beim "Server", um beim Wechseln der Sprache auch den neuen string zu bekommen(Observer-Pattern! Bei Bedarf noch mal weiter oben nachlesen ). Es wäre übrigens auch denkbar, dort bereits die string-id zu übergeben, damit die nicht immer nochmal gequeriet... äh... abgefragt werden muss.
Okay
Fabian
Eigentlich hat MS Windows ab Vista den Hang zur Selbstzerstörung abgewöhnt – mkinzler
  Mit Zitat antworten Zitat
Benutzerbild von DGL-luke
DGL-luke

Registriert seit: 1. Apr 2005
Ort: Bad Tölz
4.149 Beiträge
 
Delphi 2006 Professional
 
#20

Re: Zwei Klassen möglichst "OOP" kommunuzieren las

  Alt 6. Sep 2006, 20:44
Der Sinn von Interfaces? Die Vereinbarung von Schnittstellen. Stell dir vor, du hast Klassen, die eine mathematische Funktion darstellen. dann könntest du so ein Interface machen:

Delphi-Quellcode:
type
  IMathFunction = interface(IInterface)
    function Calculate(X: Extended):Extended;
Dann kannst du dir alle möglichen Klassen bauen, die eine beliebige Funktion darstellen und eben einfach über das Interface angesprochen werden können.
Das ginge natürlich mit einer abstrakten Basisklasse auch:

Delphi-Quellcode:
type
  TMathFunction = class {abstract} //abstract erst ab D2005
  public
    function Calculate(X: Extended):Extended; virtual; abstract;
  end;
Schau dir einfach mal das Interface-Tutorial auf dsdt an. ( http://dsdt.info/tutorials )
Lukas Erlacher
Suche Grafiktablett. Spenden/Gebrauchtangebote willkommen.
Gotteskrieger gesucht!
For it is the chief characteristic of the religion of science that it works. - Isaac Asimov, Foundation I, Buch 1
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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 04:52 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