AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Interfaces

Ein Thema von 3_of_8 · begonnen am 1. Nov 2005 · letzter Beitrag vom 3. Nov 2005
Antwort Antwort
Seite 3 von 3     123   
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#21

Re: Interfaces

  Alt 2. Nov 2005, 13:36
Außerdem wird vom Compiler die Implementierung aller Interface-Member erzwungen, bei Ableitungen von abstrakten Klassen müssen nicht alle abstrakten Methoden überschrieben werden (dafür gibt es zur Laufzeit ggf. EAbstractError-Exceptions).
Das gilt jedenfalls unter Delphi.Win32, unter .NET muss z.B. jede Klasse, die einen abstrakten Member enthält, mit dem Modifier "abstract" deklariert werden. Solange die Klasse "abstract" ist, kann sie nicht instanziiert werden.
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
Benutzerbild von maximov
maximov

Registriert seit: 2. Okt 2003
Ort: Hamburg
548 Beiträge
 
Delphi 2005 Professional
 
#22

Re: Interfaces

  Alt 2. Nov 2005, 14:33
Moin,

so ich geb auch mal meinen senf dazu Schnitstellen (interfaces) sind nicht nur prima, um klassen irgendwie abstrakt zu definieren, sondern sind eine optimale entkopplungs-technick. Dh. man kann verschiedene systeme einer anwendung logisch trennen, sodass sie nur durch die schnittstelle verbunden sind - der name ist da eigentlich sehr sprechend. In delphi ist eigentlich das konzept der Events viel bekannter, was auch exessiv zur entkopplung eingesetzt wird, aber immer nur eine Information-liefern kann, da es nur eine methode definiert, was bei interfaces bekanntlich anders ist.

Ich setzt interfaces sehr gerne als strategie ein, dh, ich übergebe einer klasse ein interface, worüber sie dann informationen beziehen oder aktionen ausführen kann, die sie eigentlich nix angehen und nicht in ihrem verantwortungsbereich liegen.

Ein beispeil:
Delphi-Quellcode:
type
     ITemplateVariableStrategy = interface
   ['{FAE1E462-0E43-4B8E-A8D0-A594E0B25E67}']
      function GetVariableValue(const VarName:string{; appearance:integer}):string;
      function GetVariableOpenDelimiter:char;
      function GetVariableCloseDelimiter:char;
   end;

  TAbstractTemplate = class(TObject)
   private
      FVariableStrategy:ITemplateVariableStrategy;
    FOpenDelimiter: char;
      FCloseDelimiter: char;
   protected
      ...
   public
      constructor Create(TemplateVariableStrategy:ITemplateVariableStrategy); reintroduce;
      function Process(const Text:String):string;
   end;
In dem beispiel soll ein text-template-processor einen text auseinandernehmen und immer wenn eine variable auftaucht, sie durch ihren wert ersetzen. Weil der template prozessor wiederverwendbar sein soll, darf er nicht darüber entscheiden mit welchem zeichen einen variable (im templat-text) definiert wird. So, dafür befragt er einfach die strategie...
 FOpenDelimiter := FVariableStrategy.GetVariableOpenDelimiter; ...und ist nun informiert. Nun findet er eine variable mit einem bestimmten namen und fragt wieder die strategie welchen text er denn nun einsetzen soll, weil er es selbst nicht entscheiden kann.

Es muss nur eine instanz geben die das entscheiden kann und die entsprechenden information liefert. Das kann die aufrufende instanz selbst sein, oder eine andere instanz die dafür geschaffen wurde und natürlich das interface implementiert:
Delphi-Quellcode:
TVariableContainer = class(TInterfacedObject, ITemplateVariableStrategy)
   private
...
      function GetVariable(const Name: string): TVariable;

   public
      constructor Create(OpenChar, CloseChar:char); overload;
      constructor Create(OpenChar, CloseChar:char; Variables:array of TVariable); overload;

      function GetVariableCloseDelimiter: Char;
      function GetVariableOpenDelimiter: Char;
      function GetVariableValue(const VarName: String): String;

      procedure AddVar(aVar:TVariable);
      procedure CreateVar(const aName, aValue:string);
      procedure DeleteVar(const VarName:string);
      ...

   end;
Als beispiel. Sie wird dann mit den information gefüttert und liefert die werte direkt an den template-processor.

So wird alles dynamisch gehalten und kann sehr leicht ausgewechselt werden. Mit der definition einer schnitstelle schliesst man gewissermassen einen vertrag mit unbekannt, dass bestimmte aufgaben von ihm zu übernehmen sind, wenn er den vertrag implementiert (er kann den vertrag ja immernoch brechen, indem er exceptions schmeisst)


Das ist jetzt nur einen kleiner aspekt der schnittstellen-verwendung und sollte nur als anschauung dienen.


PS:
ich würd die referenzzählung nicht ausschalten!
mâxîmôv.

{KDT}
  Mit Zitat antworten Zitat
tigerman33

Registriert seit: 30. Jul 2005
Ort: München
423 Beiträge
 
Delphi 2005 Professional
 
#23

Re: Interfaces

  Alt 2. Nov 2005, 15:27
Ja, das Interfaces zur Mehrfachvererbung benutzt werden können war mir klar, hab meine Frage vielleicht etwas unsauber implementiert. Ich meinte nämlich eigentlich darüber hinaus. (Was natürlich nicht den Nutzen von Mehrfachvererbung herunterspielen soll)

Was die Sprachunabhängigkeit angeht: So wie ich das bis jetzt mitgekriegt habe, ist es unmöglich, aus einer DLL eine Klasse zu exportieren (warum eigentlich?) Ist das mit Interfaces möglich? Denn sonst verlagert sich doch das Problem eigentlich nur. Um ein Plugin zu schreiben, müsste ich trotzdem die Architektur des Plugins kennen und vom Interface ableiten, das dementsprechend statisch eingebunden werden müsste--genau wie bei einer Vorfahrklasse. (Ich merk gerade, dass ich mich ein bisschen im Kreis drehe. Muss erstmal nachdenken, ob eine dynamische Vorfahrklasse/-interface überhaupt funktionieren könnte. Von wegen Methoden löschen/umbenennen/Refactoring etc ).

@Khabarakh:
Echt? Bei mir hat er da noch nie gemuckt, macht zwar immer Warnungen von wegen abstrakte Klasse mit Methode XYZ etc usw wird erzeugt, aber laufen tuts. Bloß die Methode(n) aufrufen sollte man halt nicht.

@maximov:
Das hört sich sehr interessant an, muss ich mir mal genauer anschauen (hab gleich aber einen Termin => später). Aber zunächst muss ich mal devil's advocate spielen und fragen: Anstatt der Methode Interfaces zu übergeben hätte man aber doch genauso gut auch Objekte übergeben können. Also wo ist der Unterschied? Anders ausgedrückt: Angenommen, ich würde versuchen, in deinem Beispiel sämtliche Interfaces durch Objekte zu ersetzen. Wo würde es haken?
Christian
Der Computer hilft mir, Probleme zu lösen, die ich ohne Computer nicht hätte.
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#24

Re: Interfaces

  Alt 2. Nov 2005, 15:31
Zitat von tigerman33:
Bloß die Methode(n) aufrufen sollte man halt nicht.
Auf das wollte ich mich mit "ggf." beziehen, war vielleicht nicht sehr deutlich.
Zitat von tigerman33:
Was die Sprachunabhängigkeit angeht: So wie ich das bis jetzt mitgekriegt habe, ist es unmöglich, aus einer DLL eine Klasse zu exportieren (warum eigentlich?) Ist das mit Interfaces möglich
Zu beiden Fragen: http://www.delphipraxis.net/internal...?p=29930#29930
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
tigerman33

Registriert seit: 30. Jul 2005
Ort: München
423 Beiträge
 
Delphi 2005 Professional
 
#25

Re: Interfaces

  Alt 2. Nov 2005, 15:43
Oh hab ich dich missverstanden.

Ja das Beispiel im Link ist mir bekannt, sowas ähnliches ist ja auch auf der BDN-Site zu sehen. Ich war auch dabei, für eine Anwendung Plugins zu implementieren. (Liegt aber momentan auf Eis). Was mich da gestört hat, war, dass ich die Vorfahrklasse statisch, über eine Unit, einbinden muss. Ändere ich die Vorfahrklasse, muss ich alle Plugins rekompilieren.
Christian
Der Computer hilft mir, Probleme zu lösen, die ich ohne Computer nicht hätte.
  Mit Zitat antworten Zitat
xaromz

Registriert seit: 18. Mär 2005
1.682 Beiträge
 
Delphi 2006 Enterprise
 
#26

Re: Interfaces

  Alt 2. Nov 2005, 16:18
Hallo,
Zitat von tigerman33:
Ich war auch dabei, für eine Anwendung Plugins zu implementieren. (Liegt aber momentan auf Eis). Was mich da gestört hat, war, dass ich die Vorfahrklasse statisch, über eine Unit, einbinden muss. Ändere ich die Vorfahrklasse, muss ich alle Plugins rekompilieren.
Meine PlugIns funktionieren mit Interfaces in einer DLL. Geht eigentlich ganz einfach:
  • Interface definieren
  • In der DLL eine Klasse auf Basis des Interface implementieren und über eine Funktion exportieren (z. B. function LoadInterface: IMyInterface;).
  • Im Hauptprogramm DLL laden, das Interface holen und damit arbeiten.
So kann jedes PlugIn das Interface mit den Eigenschaften füllen, die es braucht und das Hauptprogramm kann drauf zugreifen, da es ja die Schnittstelle (eben das Interface) kennt.

Gruß
xaromz
  Mit Zitat antworten Zitat
Benutzerbild von maximov
maximov

Registriert seit: 2. Okt 2003
Ort: Hamburg
548 Beiträge
 
Delphi 2005 Professional
 
#27

Re: Interfaces

  Alt 3. Nov 2005, 11:38
Zitat von tigerman33:
...

@maximov:
Das hört sich sehr interessant an, muss ich mir mal genauer anschauen (hab gleich aber einen Termin => später). Aber zunächst muss ich mal devil's advocate spielen und fragen: Anstatt der Methode Interfaces zu übergeben hätte man aber doch genauso gut auch Objekte übergeben können. Also wo ist der Unterschied? Anders ausgedrückt: Angenommen, ich würde versuchen, in deinem Beispiel sämtliche Interfaces durch Objekte zu ersetzen. Wo würde es haken?
Was du als "sämtliche Interfaces" interfaces titulierst ist grad mal ein einziges kleines interface, welches innerhalb von 10 minuten deklariert ist. Und der unterschied besteht darin, das hier die systeme tatsächlich nur das tun was in ihrem verantwortungsbereich liegt. In diesem fall soll der template prozessor nur das template durchgehen und die werte einfügen, die er von extern erfragen muss, da er nur ein verarbeiter ist. Das ist sehr nützlich, da ich den variablen-container auch für das verarbeiten anderer templates recyclen kann, wenn ich das template selbst mit objekten gefüttert hätte, dann hätte ich keine zentrale instanz wo ich die werte ändern oder ergänzen kann.

Es ist sogar so, das der template-prozessor nichtmal wissen muss wie man einen text auseinander nimmt, da er ja nur nach schema-F -> zur nächsten variable geht -> namen der variable holen -> wert von strategie holen -> wert in das resultat einfügen -> und das so lange bis EOF tun muss! Für das tatsächliche verarbeiten der textdaten könnte man einen text-prozessor einsetzen, sodass folgendes ausreichend ist um ein hoch kompliziertes template zu füllen:
Delphi-Quellcode:
TextProcessor := CreateTextProcessor(Text);

   // process the template
   //
   while TextProcessor.ForwardToNextVariable do
      TextProcessor.InsertValue(
         VariableStrategy.GetVariableValue(
           TextProcessor.GetCurrentVariable));

   Result := TextProcessor.GetResult;
durch die einfachheit, klarheit und aufgabentrennung lassen sich unglaublich viele fehler quellen vermeiden, was dann end-viel zeit spart. Der textprocessor ist dann folgendermassen deklariert und wie er implementiert ist spielt ja eigentlich keine rolle:
Delphi-Quellcode:
ITextProcessor = interface
   ['{D7845C11-D65B-4780-9874-B9A1E4F656BA}']
      function ForwardToNextVariable:boolean;
      function GetCurrentVariable:String;
      procedure InsertValue(const value:string);
      function GetResult:string;
   end;
Klar kommt man mit einem schnellschuss evtl. schneller zu einem ergebnis, aber ob das auch derart wiederverwendbar und dynamsich ist - ist fraglich Hoffe das reicht als erklärung des unterschieds....zumindest sehe ich das so. ISt natürlich nicht in stein gemeisselt, denn das ist sicher noch eleganter und abgefahrener zu lösen.
mâxîmôv.

{KDT}
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 3     123   


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 05:28 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