AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Tutorials Interfaces + Factorys
Tutorial durchsuchen
Ansicht
Themen-Optionen

Interfaces + Factorys

Ein Tutorial von stahli · begonnen am 29. Jan 2015 · letzter Beitrag vom 22. Feb 2015
Antwort Antwort
Seite 1 von 2  1 2      
OlafSt

Registriert seit: 2. Mär 2007
Ort: Hamburg
284 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#1

AW: Interfaces + Factorys

  Alt 30. Jan 2015, 09:18
Es geht doch auch gar nicht darum, ob und wie man das mit Klassen hätte machen können. Solange man innerhalb von Delphi unterwegs ist, kann man alles mit Klassen erschießen und kann auf Interfaces mehr oder weniger verzichten.

Aber das ist nicht der Punkt.

stahlis Videos dienen dazu, Typen wie mir überhaupt begreiflich zu machen, wie Interfaces und das ganze Drumherum in Delphi überhaupt funktioniert. Ich mußte mich erst als totaler Nixblicker outen und einen Thread erstellen Mir hat das Video Nummer 1 klar gezeigt, das ich die Basics nun verstanden habe und die beiden anderen Videos zeigen praktische Anwendungen auf extrem niedrigen Niveau - aber genau dieses Niveau muß man haben. Denn nur dann kapiert auch einer, der es gerade erst vor 5 Minuten gerafft hat, auch wirklich.

Ich hab auch gleich einen Kandidaten gefunden, der sich diese Videos mal reinziehen sollte.
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.154 Beiträge
 
Delphi 10.3 Rio
 
#2

AW: Interfaces + Factorys

  Alt 30. Jan 2015, 10:06
Abstrakte Klassen ohne Funktionalität sind den Interfaces ähnlich, nur das sie eben Delphi sind und bleiben. Ein Interface kommt von irgendwo her, definiert einen Vertrag und wenn deine Implementierung den erfüllt, kannst Du eine Delphi-Klasse an ein PHP-Skript hängen, oder eine C-Implementierung deines Interfaces in deinem Programm. Mach das mal mit deinen abstrakten Klassen.
Darum geht es doch gar nicht... Ich finde nur es ist ein schlecht Beispiel um Interfaces zu erklären.
Der Programmieren sollte doch auf den 1. Blick sehen warum er damit arbeiten soll und nicht so "altklug" wie ich kontern können : na nana na naaaa naaaaaa... Kann ich auch ohne Interfaces...
So ist das keine Motivation.

Ich hab auch gleich einen Kandidaten gefunden, der sich diese Videos mal reinziehen sollte.
Dann schau Dir lieber mal das Video an!

Nach diesem Video habe ich mich SOFORT auf Interfaces eingestellt... Genau aus den 2 wichtigen Gründen.

- Entkoppelung
- Referenzzählung
- Shoot & Forget Code

Somit schlage ich zwei Fliegen mit einer Klappe... Meine "objecte" sind ARC kompatible und mein Code ist unabängig von einander.

Zum Beispiel wenn ich Funktionalitäten an und abschalten will...

Delphi-Quellcode:
var
  NeueRoutine : INeueRoutine;
begin
  NeueRoutine := GlobalClassManager.GetClass<INeueRoutine>;
  if Assigned(NeueRoutine)
    then NeueRoutine.MachwasTolles
    else MyMessage('Funktionalität in der Lite Version nicht enthalten');
end;
Jetzt kann ich entweder per Programmlogik das Interface nicht am Pool registrieren... oder die Unit ist ggf. gar
nicht im Projekt enthalten, denn in der Unit steht:

Delphi-Quellcode:
Initialization
  GlobalClassManager.RegisterClass<INeueRoutine,TNeueRoutine>;
oder eben per Logic

Delphi-Quellcode:
Initialization
  if Lizenz.Can_NeueRoutine then
    GlobalClassManager.RegisterClass<INeueRoutine,TNeueRoutine>;
Für die Implementation gibt es 2 Wege... (Wahrscheinlich hunderte)

Entweder

Delphi-Quellcode:
Unit neueRoutine;

Interface
type
   INeueRoutine = Interface
     Procedure MachWasTolles;
   end;
Implementation
type
   TNeueRoutine = Class(TInterfacedObject,INeueRoutine)
                   private
                     Procedure MachWasTolles;
                  end;
...
So mach Ich es... Bedeutet jedoch auch wenn ich das Interface nicht am Pool Registriert habe... Die Unit ist wegen dem Interface immer dabei.

oder
Delphi-Quellcode:
Unit MyInterfaces;

Interface

type
   INeueRoutine = Interface
     Procedure MachWasTolles;
   end;

Implementation

end.

// ---------------------------------------

Unit NeueRoutine;

Interface
// NIX
Implementation

Uses ClassManager,MyInterfaces;

type
   TNeueRoutine = Class(TInterfacedObject,INeueRoutine)
                   private
                     Procedure MachWasTolles;
                  end;
...
Der Vorteil vom 1. Weg liegt auf der Hand... Ich kann dem Kunden einfach einen neuen Registrierungscode zusenden und schon kann er das Programmteil nutzen. (InApp-Käufe)

Der 2. Weg macht die Exe kürzer (Wenn das "neue" nicht dabei ist).

Naja und auf jeden Fall kann ich die Klasse unter ARC (Mobile) genauso verwenden wie unter OSX/Windows...

3. Grund Shoot & Forget

Delphi-Quellcode:
Var
  AndererCode : IAndererCode;
begin
  AndererCode.MachwasUndWegDamit; // Class Function Return IAndererCode;
end;
Mavarik
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.352 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: Interfaces + Factorys

  Alt 30. Jan 2015, 10:28
@Mavarik

Ich bin ein Freund der kleinen Schritte und wollte zunächst einmal aufzeigen, wie und wozu man von der bisherigen Arbeit mit normalen Klassen zu Interfaces wechseln kann.

Dependency Injection und das Spring Framework sind sicher nicht hilfreich, um Interface-Neulingen ein Grundverständnis zu vermitteln.

Es ist ja nicht ausgeschlossen, dass man mit einiger Erfahrung dann den Schritt gehen will, aber das Thema ist hier deutlich verfrüht (und wäre besser in einem eigenen Thread aufgehoben).
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#4

AW: Interfaces + Factorys

  Alt 30. Jan 2015, 11:49
...Mach das mal mit deinen abstrakten Klassen.
Darum geht es doch gar nicht...
Äh doch.

Grundkurs Taschenrechner:
Lehrer: "Wir tippen [1] [+] [1] [=] und haben das Ergebnis"
Schüler: "Wieso tippen? Das rechne ich im Kopf aus".

G-r-u-n-d-k-u-r-s

... Verstehst Du?
  Mit Zitat antworten Zitat
Benutzerbild von Mavarik
Mavarik

Registriert seit: 9. Feb 2006
Ort: Stolberg (Rhld)
4.154 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: Interfaces + Factorys

  Alt 30. Jan 2015, 13:41
G-r-u-n-d-k-u-r-s

... Verstehst Du?
Motivation
... Verstehst Du?

Ein G-r-u-n-d-k-u-r-s der mir sagt..
- boh viel tipperei
- boh aufwending

Und dann eigentlich kein Lernziel nennt...

Mavarik
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.045 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#6

AW: Interfaces + Factorys

  Alt 30. Jan 2015, 14:50
Argh, Service Locator Antipattern. Den Code, den Nick da irgendwann mal gezeigt hat, muss ich den Leuten heute noch immer wieder austreiben.

Bitte bitte. Auch wenns auf den ersten Blick clever auschaut, seine Software so zu entkoppeln, macht man es auf lange Sicht nur viel schlimmer.
Und außerdem ist das keine Dependency Injection. Du injektest da nix, sondern greifst über einen SL auf eine an anderer Stelle registrierte Instanz zu.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight

Geändert von Stevie (30. Jan 2015 um 14:57 Uhr)
  Mit Zitat antworten Zitat
OlafSt

Registriert seit: 2. Mär 2007
Ort: Hamburg
284 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#7

AW: Interfaces + Factorys

  Alt 30. Jan 2015, 21:54
Ihr seht ja selbst, wohin das führt. Ich als jemand, der man gerade eben geschnallt hat, wie das überhaupt funktioniert (bin noch immer erstaunt, das ich einen Klassenkonstruktor aufrufe, aber ein Interface bekomme), wird hier mit 3 Posts bereits total überfordert.

Spring4D ? Dependency Injection ?
Zitat:
Jetzt kann ich entweder per Programmlogik das Interface nicht am Pool registrieren
Wat fürn Pool denn ? Und was ist GlobalClassManager ? F1 bringt da nix zutage... Natürlich kann ich Google quälen, doch die Ergebnisse, die man dabei präsentiert bekommt, sind einfach vier Hausnummern zu hoch.

Versteht ihr ? Ihr redet hier von Dingen, die im 8. oder 9. oder auch erst 28. Schritt interessant werden. An die Leute, die die anderen 7,8,27 Schritte noch nicht gemacht haben, denkt ihr dabei nicht. Das ist vergleichbar mit dem Lerneffekt, den man hat, wenn man einem Anfänger, der gerade kapiert hat, was eine Schleife ist, versucht eine doppelt verkettete Liste zu erklären. Kann er nicht kapieren, weil zwischen "gerade Schleife verstanden" und "Zeiger auf Objekte" noch ein paar Schritte liegen, die man einfach nicht überspringen kann.

Ergo: Auf genau diese Leute, die ein paar Schritte noch nicht gemacht haben, auf diese zielt Stahli mit seinen drei Videos. Und ich bin ausgesprochen neugierig, wie das wohl weitergeht. Besonders spannend ist es doch, wenn wir an das Thema Daten herankommen.

Ich denke da noch immer an meine Dekoder-Klassen. Spätestend, wenn ich denen irgendeinen Binärkrams zu futtern gegeben habe und die dekodierten Daten bereitstehen, muß ich da ran. Geht sowas und wenn ja, wie ? Und irgendwann sind wir dann so weit, das wir sowas in eine DLL stopfen. Und noch etwa später soweit, das wir diese DLL auch mit C# in .NET-Umgebungen benutzen können.

Meinetwegen dürfen das gerne weiter Enten und Adler und Boote sein - ob diese Art Klassen Sinn machen oder nicht, ist für das Tutorial und das Verstehen echt sensationell unwichtig, solange man die Mechanik kapiert.

Geändert von OlafSt (30. Jan 2015 um 22:00 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.352 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Interfaces + Factorys

  Alt 30. Jan 2015, 23:09
Hallo Olaf, freut mich, dass sich noch jemand auf meiner Ebene herum treibt...

Ich will mal noch ein paar Dinge aufgreifen:


@alda

Die Testbarkeit von Klassen wird durch Interfaces erleichtert und eigentlich erst richtig ermöglicht. Das habe ich verstanden.
Man kann also echte Funktionalitäten (z.B. komplizierte Berechnungen oder Datenbeschaffungen) mal schnell durch eine Dummyklasse ersetzen, die mal schnell ein paar statische Testdaten bereitstellt.
Wenn die echte Klasse und die Dummyklasse die gleiche benötigte Schnittstelle unterstützen kann man sie ja einfach mal schnell austauschen.

IDateninterface := TEchteKlasse.Create;
oder
IDateninterface := TDummyKlasse.Create;

Ansonsten funktioniert alles andere unverändert.
Mehr als diese grobe Zusammenfassung kenne ich selbst aber nicht.


@Mavarik
Du hast Recht mit Deiner Bemerkung zur Alternative "Basisklasse".
In meinem ersten Videoversuch bin ich darauf auch noch eingegangen (den habe ich aber aus bestimmten Gründen entsorgt ) und im zweiten habe ich das dann vergessen. Aber zumindest habe ich ja erläutert, dass beide Klassen unabhängig voneinander sind. Das Beispiel bezieht sich also auf Fälle, wo es keine gemeinsame Basisklasse gibt.


@OlafSt

Also auf die Daten bin ich nur aus Zeitgründen nicht eingegangen (und weil ich es schon für so logisch und normal hielt )
Propertys, Getter und Setter definiert man im Interface genau so wie in der Klasse (man muss aber alles komplett definieren - es reicht also nicht, nur "property Value: Integer;" zu schreiben und in der Klasse dann zusätzlich Getter und Setter zuzuweisen).
In der Klasse wird dann natürlich i.d.R. noch ein privates Feld "fValue: Integer" eingeführt, wovon das Interface nichts weiß und nichts wissen soll.
Auf den Wert kannst Du dann ganz normal über IMyInterface.Value zugreifen. Der tatsächliche Speicherung des Wertes in fValue oder im Internet oder einer Datenbank regelt dann (im Verborgenen die Klasse).
Das ist gerade ein schönes Beispiel für den Testfall oben: Die echte Klasse holt den Wert vielleicht aufwendig aus dem Internet und eine vorläufige Testklasse liefert ihn vorläufig mal schnell eben statisch zurück.

Mit dem Einbinden von DLL´s habe ich mich noch nicht befasst. Aber wenn man das tut und z.B. einer Schnittstelle IXyz benutzt (mit einer zugewiesenen GUID) dann könnte in der DLL auch eine Klasse mit dieser Schnittstelle (gleiche GUID) bereitgestellt und vom Projekt benutzt werden.
Heute haben wir TVerbrennungsmotor und TElektromotor und in 5 Jahren kann dem Projekt von außen noch ein TWarpAntrieb bereitgestellt werden wenn er die gleiche Schnittstelle implementiert.
Ich kenne das aber auch nur bis hierher und näheres weiß ich nicht - auch nicht, ob Delphi-Schnittstellen irgendwie von .NET verwendet werden können (oder anders rum).


@all: Mehrfachvererbung und Interfaces

Falls jemand einen Account bei Video2Brain hat oder sonst an das Video kommt möchte ich https://www.video2brain.com/de/video...rosse-training von Mirko Matytschak empfehlen.
Das Tutorial betrifft zwar C# aber die Beiträge
- Mehrfachvererbung und
- Schnittstellen
sind sehr allgemein gehalten und sehr informativ.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli (30. Jan 2015 um 23:44 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.352 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Interfaces + Factorys

  Alt 30. Jan 2015, 23:33
Mal noch ein Versuch, die Beziehung Objekt <-> Schnittstellen zu verbildlichen:

- es wird immer zunächst ein OBJEKT erzeugt
- es wird auch immer mit dem (allerdings nicht komplett sichtbaren) OBJEKT gearbeitet
- das Objekt kann mehrere Interfaces implementieren
- alle Interfaces sind Teil des Objektes.
- entsprechend können die Interfaces auch auf die privaten Bereiche und Daten des Objektes zugreifen

- eigentlich SIND die Interfaces das Objekt
- man kann das als eine Art casting ansehen: z.B. SchnittstelleA(Objekt), SchnittstelleB(Objekt) oder SchnittstelleC(Objekt)

- somit kann man ermitteln, ob Objekt InterfaceA implementiert oder das InterfaceC das InterfaceB
- entsprechend kann man dann auch das Interface(Objekt) in InterfaceA casten oder das InterfaceC in InterfaceB

- immer wenn eine Schnittstelle verwendet wird, ist damit letztlich das Objekt dahinter genutzt, aber mit einer Art Maskierung

Bei TInterfacedObject-Ableitungen kommt noch hinzu, dass der Compiler bei jeder ObjektAlsInterfaceX-Verwendung einen Zähler hochzählt (im Bild 1..5) und beim verlassen des Scopes oder Zuweisung eines anderen Objektes (oder NIL) an die Interface-Variable den Zähler wieder verringert. Kommt der Zähler bei 0 an, wird das Objekt freigegeben.

Bei Benutzung eines Interfaces benutzt man also das Objekt, jedoch mit einer eingeschränkten Sicht und einer etwas anderen Verhaltensweise.

Wegen dieser automatischen Referenzzählung und der automatischen Freigabe des Objektes bei "Zähler = 0" sollte man unbedingt vermeiden, das Objekt mal als Objekt und mal als Interface zu benutzten. Auch die Lebenszeitverwaltung über einen Owner wäre fatal.
Entweder das Objekt ganz normal verwenden und dieses später freigeben oder dieses nach dem Create nur noch über Interfaces nutzen und den Lebenszyklus automatisch regeln lassen.


Olaf, entschärft das die Mystik etwas?
Miniaturansicht angehängter Grafiken
if.jpg  
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli (31. Jan 2015 um 00:11 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Harry Stahl
Harry Stahl

Registriert seit: 2. Apr 2004
Ort: Bonn
2.558 Beiträge
 
Delphi 12 Athens
 
#10

AW: Interfaces + Factorys

  Alt 31. Jan 2015, 00:54
Also mir haben die Videos gefallen, ich finde das ist ein guter Einstieg ins Thema. Sicher kann man noch mehr mit Interfaces machen, aber wenn man da direkt die komplexen Sachen mit erklären würde, wäre es eben kein Einstieg mehr.

Jedenfalls wurden grundlegende Funktionalitäten gut und nachvollziehbar dargestellt. Da ich selber weiß, wieviel Arbeit mit solchen Videos vebunden ist, kann ich nur sagen, vielen Dank Stahli.

Freut mich zudem, das Delphi auch noch weiterhin ein Thema für Dich ist.
  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 22:15 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz