![]() |
AW: Architektur / Projektstruktur / zirkuläre Referenz Problem
Ich hatte das Problem/Thema auch schon einmal angesprochen:
![]() Bisher habe ich Interfaces immer vermieden und lieber "richtige Objekte" verwendet. Der Mehraufwand, extra Interfaces zu definieren, hat sich für mich nicht gerechnet. Da ich inzwischen aber auch stärker auf Trennung von Projektteilen achte, scheint das Konzept von neo4a aber doich nicht uninteressant. Mal sehen, vielleicht im nächsten Projekt... ;-) |
AW: Architektur / Projektstruktur / zirkuläre Referenz Problem
Ich möchte Dir noch bei Deinen Untersuchungen einen Tipp resp. Warnung mitgeben: Die Arbeit mit Interfaces kann sich zu einem Albtraum entwickeln, weil je nach Implementierung die Freigabe der Objekte variiert und automatisch durch Delphi vorgenommen werden kann.
Hier hilft Dir ein Framework wie das schon erwähnte Delphi-Spring und kann Dir in der Folge sehr viel Frust abnehmen. Auf jeden Fall solltest Du in deiner dpr aktivieren:
Delphi-Quellcode:
begin
ReportMemoryLeaksOnShutdown := DebugHook <> 0; Application.Initialize; |
AW: Architektur / Projektstruktur / zirkuläre Referenz Problem
Zitat:
Für Interfaces wird häufig der Vergleich zu Lampen in Häusern bemüht: Solange Du Deine Lampen nur einmalig installierst, kannst Du sie direkt ans Stromnetz anschließen (wird ja so bei den Deckenlampen gemacht). Portable Lampen haben einen Stecker und der Stecker passt in die Dose (der E-Dienst), der es egal ist, ob da eine Lampe, ein Toaster .... Solange der Stecker passt gibt's Strom, egal, was das Gerät damit macht. Genauso kann man die Aufgabe von Interfaces auffassen: Sie verbergen den zu verbindenen Software-Teilen einander die jeweilge Funktionalität. Damit wird Dein Code "industrialisiert", d.h. modular, wartbar, testbar. Die Künstler unter uns werden nun weinen, aber das ist dann halt so. |
AW: Architektur / Projektstruktur / zirkuläre Referenz Problem
...nur hat die Industrie keine Probleme mit Speicherlecks.
Meine Grundregel: Entweder die Objekte NIE oder IMMER als Interface ansprechen. Dann gibts keine Probleme mit der Referenzzählung. |
AW: Architektur / Projektstruktur / zirkuläre Referenz Problem
Zitat:
Zitat:
|
AW: Architektur / Projektstruktur / zirkuläre Referenz Problem
Zitat:
|
AW: Architektur / Projektstruktur / zirkuläre Referenz Problem
Nochmal ein Danke an alle die hier bisher geantwortet haben. Allerdings hab ich nun ein Verständnisproblem in Bezug auf Vererbung. Normalerweise würde ich dafür einen neuen Thread eröffnen, aber da die Erklärung des Problems auf der bereits am Anfang gelisteten Erklärung basiert, packe ich das mal hier mit hinzu.
Und zwar existiert ja wie gesagt ein Engine-Objekt und (später) mehrere Manager. Diese sollen von einer Basisklasse abgeleitet werden. Nun ergibt sich grob zusammengefasst folgende Konstruktion.
Delphi-Quellcode:
unit ICE_Interfaces;
interface const IID_IICEEngine: TGUID = '{1E017D9B-7CA7-4D5E-A124-09A11C38956C}'; IID_IICEEngineObject: TGUID = '{4B79DEA1-B898-4604-8F34-BC7F9D9575CA}'; IID_IICEResourceManager: TGUID = '{B773EEA0-5055-4519-8D91-BAAD290712BD}'; { Forward. } type IICEEngine = interface; IICEEngineObject = interface; IICEResourceManager = interface; IICEEngine = interface(IUnknown) ['{1E017D9B-7CA7-4D5E-A124-09A11C38956C}'] function GetResourceManager: IICEResourceManager; safecall; property ResourceManager: IICEResourceManager read GetResourceManager; end; IICEEngineObject = interface(IUnknown) ['{4B79DEA1-B898-4604-8F34-BC7F9D9575CA}'] function GetEngine: IICEEngine; safecall; property Engine: IICEEngine read GetEngine; end; IICEResourceManager = interface(IICEEngineObject) ['{B773EEA0-5055-4519-8D91-BAAD290712BD}'] end; implementation end.
Delphi-Quellcode:
unit ICE_BaseClasses;
interface uses ICE_Interfaces; type TICEEngineObject = class(TInterfacedObject, IICEEngineObject) private FEngine: IICEEngine; function GetEngine: IICEEngine; protected function _GetEngine: IICEEngine; safecall; { IICEEngineObject } function IICEEngineObject.GetEngine = _GetEngine; public constructor Create(e: IICEEngine); virtual; property Engine: IICEEngine read GetEngine; end; implementation { TICEEngineObject } constructor TICEEngineObject.Create(e: IICEEngine); begin FEngine := e; end; function TICEEngineObject.GetEngine: IICEEngine; begin Result := FEngine; end; function TICEEngineObject._GetEngine: IICEEngine; begin Result := Engine; end; end.
Delphi-Quellcode:
IICEResourceManager erbt von IICEEngineObject.
unit ICE_ResourceManager;
interface uses Classes, SysUtils, ICE_BaseClasses, ICE_Interfaces; type TICEResourceManager = class(TICEEngineObject,IICEResourceManager) private protected public constructor Create(e: IICEEngine); override; end; implementation { TICEResourceManager } constructor TICEResourceManager.Create(e: IICEEngine); begin inherited Create(e); end; initialization finalization end. Genaue wie TICEResourceManager von TICEEngineObject.
Code:
Nun bekomme ich beim kompilieren folgende Fehlermeldung "[Pascal Fehler] ICE_ResourceManager.pas(40): E2003 Undefinierter Bezeichner: 'GetEngine'".
TICEEngineObject -> implementiert -> IICEEngineObject
| | Ableitung Ableitung | | TICEResourceManager -> implementiert -> IICEResourceManager Manchmal seh ich glaube ich den Wald vor lauter Bäumen nicht. Ich kann diese Fehlermeldung in diesem Zusammenhang nicht nachvollziehen bzw. sehe keine Begründung dafür. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:17 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