Delphi-PRAXiS
Seite 3 von 7     123 45     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Tutorials und Kurse (https://www.delphipraxis.net/36-tutorials-und-kurse/)
-   -   Interfaces + Factorys (https://www.delphipraxis.net/183702-interfaces-factorys.html)

Sir Rufo 31. Jan 2015 15:05

AW: Interfaces + Factorys
 
Zitat:

Zitat von DeddyH (Beitrag 1288400)
IIRC stimmt das so nicht ganz. Wenn man das Interface nutzt, zeigt zwar die Codevervollständigung Getter und Setter nicht an, sie lassen sich aber trotzdem direkt aufrufen. Das ist zwar Quark, aber wohl nicht zu ändern.

Und was ist technisch gesehen der Unterschied zwischen dem impliziten und expliziten Aufruf von Getter und Setter?

Aus welchen technischen Gründen werden bei Klassen die Getter/Setter idR nicht public deklariert?

stahli 31. Jan 2015 15:24

AW: Interfaces + Factorys
 
Technisch gesehen ist das natürlich gleich.
Aber wenn man sich erst neu mit Interfaces befasst kann halt etwas undurchsichtig sein und Einsteiger verstehen die Zusammenhänge nicht direkt.

Wenn man erst mal verstanden hat wie es läuft, dann kommt man damit allerdings zurecht - geht jedenfalls mir so.
Jedenfalls weiß ich jetzt, dass ich Getter und Setter deklarieren muss, mir die Codevervollständigung diese aber nicht andauernd unter die Nase reibt wenn sie privat sind.

Damit kann ich leben.

Sir Rufo 31. Jan 2015 15:28

AW: Interfaces + Factorys
 
Das mit dem Getter/Setter muss ich doch schon ohne Interfaces verstanden haben und warum diese idR nicht als public deklariert werden. Dann versteht man auch warum es schnurz ist, wenn man doch darauf zugreifen kann (weil das technisch bedingt bei Interfaces so ist und nicht anders möglich ist).

DeddyH 31. Jan 2015 15:28

AW: Interfaces + Factorys
 
Wofür braucht man technisch gesehen überhaupt Sichtbarkeiten?

Sir Rufo 31. Jan 2015 15:30

AW: Interfaces + Factorys
 
Zitat:

Zitat von DeddyH (Beitrag 1288421)
Wofür braucht man technisch gesehen überhaupt Sichtbarkeiten?

Bei einer public Property werden die Getter/Setter nur aus kosmetischen Gründen nicht public deklariert, eben aus dem gleichen Grund warum die Codevervollständigung bei Interfaces die Getter/Setter nicht anzeigt.

stahli 1. Feb 2015 11:00

AW: Interfaces + Factorys
 
Jetzt muss ich noch etwas zum Video 2 + 3 nachfragen (Stand hochgeladenes Projekt vom ersten Beitrag).

Ich habe zwei Fahrzeuge, die einen Motor haben (Auto und Boot).
Jetzt könnte man sich noch ein Elektrofahrrad einführen, hätte also 3 Klassen mit einem Motor.

Wenn IMotor StarteMotor und Tanken implementiert, müssen das die 3 Klassen auch unmittelbar tun.
Auto und Boot könnten aber mit einem Benzin-, Diesel- oder Elektromotor ausgestattet werden.

Wäre es somit nicht vielleicht sinnvoll, eine Klasse TMotor UND dazugehörige Schnittstelle IMotor einzuführen?

Dann könnten die Fahrzeuge so aussehen:

Bsp. Auto:
Delphi-Quellcode:
  TAuto = class(TInterfacedObject, IHasMotor)
  private
    FMotor: IMotor;
      FAnzahlRaeder: Integer;
      procedure SetAnzahlRaeder(const Value: Integer);
      procedure Fahre;
    //procedure StarteMotor;
    //procedure Tanken;
  public
    property Motor: IMotor read get_Motor write set_Motor;
      property AnzahlRaeder: Integer read FAnzahlRaeder write SetAnzahlRaeder;
  end;
Die Interfaces könnten dann so aussehen:

Delphi-Quellcode:
  IMotor = interface
    procedure StarteMotor;
    procedure Tanken;
  end;

  IHasMotor = interface
    function get_Motor: IMotor;
    procedure set_Motor(const Value: IMotor);
    property Motor: IMotor read get_Motor write set_Motor;
  end;
So könnte man dem Auto verschiedene Motoren hinzufügen.
Allerdings könnte ein Elektromotor dann nicht tanken sondern man würde die Batterie aufladen.
Ich muss also zur Laufzeit ggf. immer prüfen, welcher Motor eingebaut ist und ob überhaupt einer existiert.

Klar, man kann der Fabrik schon sagen: Gib mir ein Auto mit Elektromotor zurück, aber zur Laufzeit weiß man ja dann dennoch nicht, was man nun genau vorliegen hat.

An der Stelle komme ich nicht ganz weiter.
Wie würdet Ihr damit umgehen? (Aber bitte nicht auf das Spring-Framework o.ä. verweisen, damit das hier nachvollziehbar bleibt.)

Sir Rufo 1. Feb 2015 11:14

AW: Interfaces + Factorys
 
Mal ganz weg von der Programmierung, aber das Betanken an und für sich im Sinne von "fülle das nach, damit der Motor arbeiten kann" ist doch für jeden Motor in diesem Sinne gleich.

Das was man tankt muss zum Motor passen, aber "Tanken" müssen sie alle (vor allem weil "Tanken" das Befüllen eines "Tanks" -> Vorratsbehälters beschreibt ohne dabei das Tankgut oder den Tank irgendwie einzuschränken).

Also ist Tanken als Methode völlig ok (wenn das, was man tankt in diesem Kontext keine Rolle spielt bzw. spielen muss).

Einen konkreten Dieselmotor würde man dann mit einer Verbindung zu einem Diesel-Lieferanten erzeugen, den Benzinmotor mit einer Verbindung zu einem Benzin-Lieferanten und den Elektromotor mit einem Strom-Lieferanten. ;)

stahli 1. Feb 2015 11:33

AW: Interfaces + Factorys
 
Den Unterschied zwischen Tanken und Aufladen habe ich nur exemplarisch ins Spiel gebracht.
Es kann ja in echten Fällen möglicherweise Unterschiede geben, die für den weiteren Verlauf relevant sind.

Das ERZEUGEN eines Autos mit einem bestimmten Motor sehe ich nicht als Problem.
Aber später müsste ich immer prüfen:
- Kann das Objekt, das ich hier habe einem Motor haben?
- Hat es tatsächlich einen Motor?
- Kann ich damit tanken und was oder an die Steckdose?

Würdest Du also meine zwei Schnittstellen IMotor (die dann eine tatsächliche Motorinstanz representiert) und eine Schnittstelle IHasMotor (oder eigentlich besser: IKannMotorHaben) (die einem Auto und Boot hinzugefügt wird, nicht aber einem Fahrrad oder Vogel) sinnvoll finden?

Sir Rufo 1. Feb 2015 11:33

AW: Interfaces + Factorys
 
Man kann das mit dem Motor auch anders darstellen
Delphi-Quellcode:
IBetriebsstoffQuelle = interface
  function GetBetriebsstoffArt : Integer;
  procedure Entnehme( AMenge : Single );
end;

IMotor = interface
  procedure Tanken( AQuelle : IBetriebsstoffQuelle );
end;
Jetzt kann der Motor prüfen, ob die Quelle den richtigen Betriebsstoff liefert und sich die benötigte Menge entnehmen. ;)

Sir Rufo 1. Feb 2015 11:44

AW: Interfaces + Factorys
 
Zitat:

Zitat von stahli (Beitrag 1288450)
Den Unterschied zwischen Tanken und Aufladen habe ich nur exemplarisch ins Spiel gebracht.
Es kann ja in echten Fällen möglicherweise Unterschiede geben, die für den weiteren Verlauf relevant sind.

Das ERZEUGEN eines Autos mit einem bestimmten Motor sehe ich nicht als Problem.
Aber später müsste ich immer prüfen:
- Kann das Objekt, das ich hier habe einem Motor haben?
- Hat es tatsächlich einen Motor?
- Kann ich damit tanken und was oder an die Steckdose?

Würdest Du also meine zwei Schnittstellen IMotor (die dann eine tatsächliche Motorinstanz representiert) und eine Schnittstelle IHasMotor (oder eigentlich besser: IKannMotorHaben) (die einem Auto und Boot hinzugefügt wird, nicht aber einem Fahrrad oder Vogel) sinnvoll finden?

Das ist immer genau das Problem an diesen "an den Haaren herbeigezogenen" Beispielen, wo man Enten, Fahrräder und Autos irgendwie gleich behandeln will. Man kommt nicht so richtig ins vorne und stösst dabei auch eben auf die besagten Probleme.

Sinnvoller erscheint mir etwas wie
Delphi-Quellcode:
IMotorBetrieben = interface
  funtion GetMotor : IMotor;
end;

IMobil = interface
  procedure BewegeZu( Ort : TPoint );
end;

IKannSprechen = interface
  procedure Sage( AText : string );
end;
Mit
Delphi-Quellcode:
Supports
fragt man dann ab, ob dieses oder jenes Interface unterstützt wird und führt das dann aus:
Delphi-Quellcode:
procedure Sage( AText : string; AContext : IInterface );
var
  LSprecher : IKannSprechen;
begin
  if Supports( AContext, IKannSprechen, LSprecher ) then
    LSprecher.Sage( AText );
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:50 Uhr.
Seite 3 von 7     123 45     Letzte »    

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