![]() |
Zugriff auf Public nur wenn Bedingung erfüllt ist
Hallo,
irgendwie hab ich grad nen Knoten im Kopf. Ich würde gerne folgendes erreichen, falls irgendwie sauber machbar: Sagen wir mal es gibt eine Basisklasse: TUpdateEngine und mehrere weitere Klassen abhängig vom Betriebssystem z.b. TWin7, TWinVista, TWinXP Die Basisklasse TUpdateEngine soll beim Create prüfen, um welches Zielbetriebssystem es sich handelt. Wenn das erledigt ist, sollen nur die Funktionen und Proceduren aus dem Publicteil von aussen ansprechbar sein, die auch zum Zielbetriebssystem passen. Diese Functionen und Proceduren möchte ich gerne in die Klassen TWin7 usw. auslagern. Mir ist nicht klar, wie ich die Klassen aufbauen muss, damit dies möglich ist, sollte es überhaupt möglich sein? Zu mal ich gerne alles in einer Unit unterbringen würde. Vielleicht kann mir jemand mal auf die Sprünge helfen... Viele Grüsse s! |
Re: Zugriff auf Public nur wenn Bedingung erfüllt ist
Führe die entsprechenden Eigenschaften erst in den jeweiligen Unterklassen ein.
|
Re: Zugriff auf Public nur wenn Bedingung erfüllt ist
Ok,
Aber wie komm ich von der TUpdateEngine nach z.b. TWin7 mit den Functionen für Win7 nach dem ermitteln des Betriebssystems in TUpdateEngine? Das ist mir nicht klar. |
Re: Zugriff auf Public nur wenn Bedingung erfüllt ist
Delphi-Quellcode:
Tja und nun könnte man extern in den Ableger casten, welcher erstellt wurde.
type
TWin7 = class(TUpdateEngine) ... end; TWinVista = class(TUpdateEngine) ... end; TWinXP = class(TUpdateEngine) ... end; function GetEngine(): TUpdateEngine; begin if TheSystem = '7' then Result := TWin7.Create else if TheSystem = 'Vista' then Result := TWinVista.Create else if TheSystem = 'XP' then Result := TWinXP.Create else Fehler; end;
Delphi-Quellcode:
Ansonsten alles in TUpdateEngine reinmachen und nur die Zugriffe auf die Property/Funktionen intern unterdrücken (eventuell mit Exceptions), welche im aktuellen System nicht verfügbar sind.
var Engine: TUpdateEngine;
Engine := GetEngine; Engine.MachWasWelchesÜberallGeht; if Engine.isWinXP then // oder if Engine is TWinXP then TWinXP(Engine).MachEtwasWelchesNurInWin7Geht; |
Re: Zugriff auf Public nur wenn Bedingung erfüllt ist
Zitat:
Irgendwie nicht mein Tag heute :cry: |
Re: Zugriff auf Public nur wenn Bedingung erfüllt ist
Das geht z.B. bei Methoden, wenn du die Abfrage in disen machst und beim falschen OS eine Exception auslöst.
Besser ist aber die andere Alternativ, da sie dem Prinzip der OOP folgt |
Re: Zugriff auf Public nur wenn Bedingung erfüllt ist
Zitat:
Delphi-Quellcode:
TUpdateEngine = class
property isWin7: Boolean ...; procedure NurFürWin7; procedure NurFürWin7oderXP; end; procedure TUpdateEngine.NurFürWin7; begin if not isWin7 then raise Exception.Create('ist nicht erlaubst'); ... end; procedure TUpdateEngine.NurFürWin7oderXP; begin if not (isWin7 or isWinXP) then raise Exception.Create('ist nicht erlaubst'); ... end; |
Re: Zugriff auf Public nur wenn Bedingung erfüllt ist
Zitat:
Also Cast wäre besser wenn ich das richtig verstehe als die Exceptionmethode? |
Re: Zugriff auf Public nur wenn Bedingung erfüllt ist
Zitat:
Zudem finde ich eine inflationäre Verwendung von Exceptions auch nicht so gut. (Fahrt nach Gehör statt nacht Sicht) |
Re: Zugriff auf Public nur wenn Bedingung erfüllt ist
[quote="mkinzler"]
Zitat:
Ok da ist was dran hehe, dann lass ich mir mal ne Badewanne mit Kaffee ein und leg mal los! Vielen Dank euch beiden! :thumb: |
Re: Zugriff auf Public nur wenn Bedingung erfüllt ist
Hallo Leute,
auch wenn ich nicht alles genau gelesen habe, häng' ich mich mal mit rein. Das mit dem Cast ist doch auch nicht DIE Lösung oder? Mann muss vor jeder Verwendung Testen, was man erzeugt hat! Wie wär's mit "leeren" Methoden: Alles in die Bassis-Klasse. Virtuelle Methoden, nicht abstrakt! Und die abgeleiteten Klassen einfach gezielt überschreiben. So kann man auch die "falschen" Methoden aufrufen, welche dann halt nichts unternehmen. |
Re: Zugriff auf Public nur wenn Bedingung erfüllt ist
Zitat:
> jedenfalls sieht es ja von außen so aus ... wenn intern nix gemacht wird und es darüber keine Rückmeldung gibt. Zitat:
und auch daß dein Vorschlag schon vorgekommen ist (allerdings mit Rückmeldung). |
Re: Zugriff auf Public nur wenn Bedingung erfüllt ist
Zitat:
Auch beim erneuten Lesen, sehe ich meine Lösung NICHT vorgekommen! Ich sehe die "Bedenken" an anderer Stelle. OOP bedeutet in meinen Augen vor allem auch Wartbarkeit. Und die Lösung, dass bei jeder Verwendung überprüft werden müss, um welches Object es sich denn eigentlich handelt, find ich einfach nur schrecklich. Zitat:
"Deine" Lösung:
Delphi-Quellcode:
Ohne Else-Zweig fehlt hier auch etwas!
if System = 'Win7' then
TWin7(winObject).machWasMitWin7(); Ansonsten kann man den Methoden einen Rückgabewert (bool) verpassen, wenn's sein muss. Meine Lösung:
Delphi-Quellcode:
Die Zweite hat folgenden Vorteil:
winObject.machWas();
Falls ich nun möchte, dass einige Aktionen nicht nur auf Win7 sondern zusätzlich noch auf WinXP ausgeführt werden sollen, so ändere ich EINE Methode (die von TWinXP) und muss nicht alle Bedingungen suchen. Von den dazu wegfallenden Prüfungen seh ich hier mal ab. |
Re: Zugriff auf Public nur wenn Bedingung erfüllt ist
Hi,
1. würde ich ein Interface erstellen, in dem alle gemeinsamen Funktionen/Prozeduren/Properties der 3 Betriebssystemklassen definiert werden. 2. Das Gleiche dann für die 3 Klassen separat. 3. Den Interfaces eine GUID verpassen dann kannst du die Supports Funktion benutzen. !Wichtig! 4. Die 3 Klassen dann vom gemeinsamen Interface und dem spezialisierten ableiten, dann müssen die F./P./P. in den 3 Klassen auch vorhanden sein, sonst komiliert er erst garnicht. 5. In den 3 Klassen nicht private/protected verwenden, sondern strict private/strict protected, dann sind diese auch in der Unit private/protected. So noch ein wenig Code:
Delphi-Quellcode:
Mit der Methode bist du wirklich OOP und auch sehr sauber.
IWindows = interface(IInterface)
['{9cd3bd90-e18a-4e4f-a720-93b515181025}'] // von [url]www.guidgenerator.com[/url] function Add(sum1, sum2: Integer): Integer; // als Beispiele function Sub(sub1, sub2: Integer): Integer; end; IWin7 = interface(IInterface) ['{e71d5c68-08ae-4f7c-8239-fd058c77f7b2}'] function Mul(mul1, mul2: Integer): Integer; end; IWinXP = interface(IInterface) ['{788e59bc-3f7a-4456-8951-8cce2abf1a71}'] function Div(div1, div2: Integer): Integer; end; TUpdateEngine = class(IWindows) function Add(sum1, sum2: Integer): Integer; function Sub(sub1, sub2: Integer): Integer; ... end; TWin7 = class(TUpdateEngine, IWin7) function Mul(mul1, mul2: Integer): Integer; ... end; TWinXP = class(TUpdateEngine, IWinXP) function Div(div1, div2: Integer): Integer; ... end; procedure ToWas; var Engine : TUpdateEngine; // oder IWindows wenn die Var. nicht inizialisiert werden muß I7 : IWin7; IXP : IWinXP; begin Engine := GetEngine; Engine.Add(); if Supports(Engine, IWin7, I7) then I7.Mul(); if Supports(Engine, IWinXP, IXP) then IXP.Div(); end; |
Re: Zugriff auf Public nur wenn Bedingung erfüllt ist
Ich finde die Variante mit dem Cast ebenfalls falsch. Denn sobald eine neue Betriebssystemklasse dazu kommt muss man wieder den gesamten Code ändern anstelle einfach nur eine neue Klasse hinzu zufügen.
Richtig wäre die Variante alles in der Basisklasse zu definieren und gegebenfalls eine Funktion mit anzulegen die zurück gibt welche der Funktionen für das entsprechende System verfügbar sind. Wenn man dann eine neue Klasse hinzufügt muss wenigstens nicht an allen Stellen geändert werden. Für mich wäre Ziel, das man einfach nur eine neue Klasse hinzufügt und sonst nichts weiter machen muss wenn ein neues System dazu kommt. |
Re: Zugriff auf Public nur wenn Bedingung erfüllt ist
Zitat:
Ziel muss es sein die Unterschiede zwischen den Windows-Versionen quasi "glattzubügeln". Hierbei kann das ![]() Es gibt dann folgende Klassen: * TWindowsUpdater (Basisklasse der drei folgenden Klassen) * TWinXP * TWinVista * TWin7 * (TWin8) Dann gibt es noch eine Faktoryklasse:
Delphi-Quellcode:
Die Faktoryklasse erzeugt passend zum Betriebssystem ein TWinXP, TWinVista oder TWin7-Objekt.
TWindowsUpdaterFactory=class(TObject)
class function CreateWindowsUpdaterObj:TWindowsUpdater; end; Zuletzt gibt es noch die Klasse TUpdateEngine. Diese Klasse bekommt von Aussen ein Objekt der Klasse TWindowsUpdater zugeteilt. Innerhalb von TUpdateEngine gibt es keine If-Abfragen oder Case-Anweisungen die sich auf das Betriebssystem beziehen. Sämtlicher Code der irgendwie Betriebssystemabhängig arbeitet ist in die TWindowsUpdater Unterklassen gewandert. Vergleiche das skizzierte System mal mit dem Konzept der Druckertreiber. Niemand der bei klarem Verstand ist würde heutzutage für jeden Druckertyp eine Druckroutine schreiben. Stattdessen gibt es eine Menge von Operationen, die vom jeweiligen Druckertreiber umgesetzt werden. Die Anwendung spürt so gut wie nichts davon, auf welchem Drucker sie ihre Ausgaben macht. |
Re: Zugriff auf Public nur wenn Bedingung erfüllt ist
Wenn es nur ums "glattzubügeln" geht dann reicht auch ein Interface mit allen public Deklarationen und dann einfach pro Betriebssystem eine Klasse von dem Interface abgeleitet. Dann die betriebssystemspezifische Umsetzung der Funktionen implementieren, die Variable betriebssystemspezifisch erzeugen und mit Supports nur das eine Interface abfragen, oder gleich so benutzen, kann ja kein anderes sein.
ABER, ich glaube darum geht es ihm nicht. Er will ja zusätzliche Funktionen die nur von einem System unterstützt werden auch implementieren. Und dann ist meine Methode die Beste. ;) |
Re: Zugriff auf Public nur wenn Bedingung erfüllt ist
Bein einfacher Vererbung ist ein Interface aber nicht unbedingt notwendig
|
Re: Zugriff auf Public nur wenn Bedingung erfüllt ist
Erstmal herzlichen Dank, für die ganzen Anregungen von euch!
Nur irgendwie, gehts mir grad so, je mehr Anregungen kommen umso verwirrter werde ich, da es anscheinend zu dem Thema sehr viele unterschiedliche Meinungen gibt (oder anders gesagt, gibt es wohl keine allgemeingültige Regel) wie man sowas am besten gestaltet :shock: :gruebel: Viele Grüsse s! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:27 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