AW: Aufbau eigene Klasse mit Property und TStrings
@Jens
Ich habe nach dem von Dir beschriebenen Schema bereits Steuerungen/Messungen umgesetzt, das funktioniert. Eine Basisklasse mit allgemeinen Eigenschaften und Ereignisbehandlungsroutinen, Fehlerroutinen (z.T. als virtual und oder abstract) und darauf die spezifischen Klassen für das Parsen/Interpretieren/Schreiben. |
AW: Aufbau eigene Klasse mit Property und TStrings
Die Frage ist doch: WER erzeugt die Objekte für die seriellen Schnittstellen?
Nach deinem Konzept nach hältst du 4 ComPort-Objekte auf dem Datenmodul bereit. Ich würde diese ComPort-Objekte aber dynamisch nach Bedarf über eine Factory-Klasse erzeugen. Diese Factory-Klasse benötigt für ihre Arbeit den Dateinamen einer Ini-Datei. Die Ini-Datei sieht z.B. so aus:
Code:
Hier der Grobentwurf der Factory-Klasse:
[Config]
DeviceCount=2 [Device1] Device=MB100 Port=COM1 Baudrate=9600 Parity=N [Device2] Device=MB256 Port=COM3 Baudrate=19200 Parity=N
Delphi-Quellcode:
In der obigen Funktion fehlen noch einige Feinheiten sowie eine wasserdichte Fehlerbehandlung.
TDeviceFactory=class
public class function CreateMB100:TAlarmAnlage; class function CreateMB256:TAlarmAnlage; ... function GetDeviceCount:integer; // Anzahl der Geräte in der Ini-Datei function CreateDevice(deviceNr:integer):TAlarmAnlage; property IniFilename:string; end; function TDeviceFactory.CreateDevice(deviceNr:integer):TAlarmAnlage; var devicename : string; inifile : TIniFile; section : string; comport : TComPort; begin section := Format('Device%d', [devicenr]); inifile := TIniFile.Create(IniFilename); devicename := inifile.ReadString(section, 'Device'); // hier ggf. prüfen, ob es die Section überhaupt gibt // Hardwarekomponente erzeugen if devicename='MB100' then Result := CreateMB100 else if devicename='MB256' then Result := CreateMB256 else if ... else raise Exception.CreateFmt('unbekanntes Device <%s>', [devicename]); // jetzt wird noch das Kommunikations-Objekt benötigt comport := TComPort.Create(Application {siehe Text unten}); comport.Port := inifile.ReadString(section, 'Port'); comport.BaudRate := inifile.ReadInteger(section, 'Baudrate'); comport.Parity := inifile.ReadString(section, 'Parity'); // hier ggf. weitere Properties (Handshake, Datenbits) berücksichtigen // Geräte-Objekt und Kommunikations-Objekt verheiraten Result.Comport := comport; comport.OnReceive := Result.ReceiveHandler; // Eventhandler zuweisen // serielle Schnittstelle öffnen comport.Connected := True; inifile.Free; end; Aber das Prinzip sollte klar sein. Die Hardwarekomponente (bzw. Geräteklasse) kümmert sich nicht um Baudrate usw. Die Factory erzeugt anhand den Informationen in der Ini-Datei die Hardwarekomponente sowie die Komponente für die serielle Schnittstelle und baut diese zu einem funktionierenden Verbund zusammen. Es bleibt noch die Frage offen: WER ist der Owner der ComPort-Komponente? Im Code oben habe ich Application angegeben; das ist noch etwas unschön. Falls die Hardwarekomponente tatsächlich eine echte Komponente ist, würde man schreiben:
Delphi-Quellcode:
Lass das mal etwas absacken; das Konzept der Factory-Klasse mag zunächst etwas fremd aussehen, hat aber entscheidende Vorteile.
// jetzt wird noch das Kommunikations-Objekt benötigt
comport := TComPort.Create(Result {=die neu erzeugte Hardwarekomponente}); comport.Port := inifile.ReadString(section, 'Port'); |
AW: Aufbau eigene Klasse mit Property und TStrings
Zitat:
Zitat:
Zitat:
Zitat:
Danke aber schon mal für die vielen Inputs. Gruß Jens |
AW: Aufbau eigene Klasse mit Property und TStrings
Bin gestern mit dem Blog-Artikel über Magic Values doch nicht mehr fertig geworden. Jetzt aber endlich: http://www.christian-rehn.de/2010/12/31/magic-values/
Zitat:
Zitat:
In diesem Fall würde ich aber auch die Factory nehmen. Egal ob jetzt von mir aus in der Factory hardgecoded oder aus ner Konfigurationsdatei gelesen. Aber deine Klasse muss von Baudrate & Co. eigentlich erstmal nix wissen. Das ist Sache von TComPort. ==> Separation of Concerns. Zitat:
Zitat:
Ich weiß nicht, was deine Klasse alles tun soll, aber, wenn sie mehr tut als das Protokoll verarbeiten (also vermutlich das, was du Parsen nennst), dann solltest du das in mehrere Klassen aufteilen. Zitat:
mfg Christian |
AW: Aufbau eigene Klasse mit Property und TStrings
Man kann und ich würde es in diesem Fall so tun, das ganze auch als hochspezialisierte/erweiterte Comportklassen sehen.
|
AW: Aufbau eigene Klasse mit Property und TStrings
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Vieleicht konnte ich meine Ziel jetzt noch etwas besser erläutern. Was mir wichtig ist, ist halt, das wenn schon eine externe Unit, das diese auch sauber Programmiert ist. Ich fange gerade halt erst mit Klassen an und da will ich halt nicht direkt den größten Bock schießen. Gruß Jens |
AW: Aufbau eigene Klasse mit Property und TStrings
Zitat:
Im Zweifel weis man nicht, wie die Setter-Methode implementiert ist. Diese könnte eine Zuweisung einer Stringliste auf eine interne Variable sein (Interne Variable wurde dann z.B. nicht im Constructor instanziert), oder eben ein Assign auf eine bereits instanzierte Variable. Daher gibt es bei mir die Konvention, daß eine interne bereits im Create instanzierte Stringliste nur über eine Function oder ein Readonly-Property zugreifbar ist.
Delphi-Quellcode:
property ComPortPropertys: TStrings read FComPortPropertys;
Delphi-Quellcode:
Eine Stringliste, die im Objekt nicht instanziert wurde, die bekommt eine Getter UND eine Setter-Methode. Mit dieser Vorgabe weis ich genau, ob das Objekt die Zerstörung der übergebenen Stringlist übernimmt. Soll die Zerstörung der zugewiesenen Stringliste nicht vom Objekt übernommen werden, dann muss vorher ein NIL zugewiesen werden, oder es gibt ein Property mit dem namen OwnsStringlist. Gilt im übrigen nicht nur für Stringlisten, sonder für alle Objekte, die in einem Objekt zugreifbar sind.
function ComPortPropertys: TStrings;
begin result:=FComPortPropertys; end; Alles andere birgt die Gefahr eines Speicherlecks oder einer Schutzverletzung. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:11 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