AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Problem mit Klassenerstellung

Ein Thema von Smeik · begonnen am 13. Dez 2016 · letzter Beitrag vom 20. Dez 2016
Antwort Antwort
Smeik

Registriert seit: 21. Mär 2016
Ort: Thüringen
6 Beiträge
 
Delphi 10.1 Berlin Professional
 
#1

Problem mit Klassenerstellung

  Alt 13. Dez 2016, 14:16
Hallo,
ich möchte eine Sensor-Steuerung per OOP abbilden.
Eine Steuerung kann unterschiedliche Art und Anzahl von Sensoren (NTC-Sensor, Druck-Sensor) und Aktoren (Relais) besitzen .
Für diese habe ich jeweils eigene Klassen erstellt, die dann in eine Steuerung eingebunden werden.
Die einzelnen Sensoren besitzen widerum Schwellwerte die einstellbar sind und bei Überschreiten und unterschreiten Fehler auslösen. Die Aktoren widerum können nur Ein/Aus geschalten werden. Wie kann ich nun in der Klasse TSteuerung die Verknüfung zwischen meinen Sensoren und Aktoren am besten herstellen bzw. konfigurierbar machen. Bsp. Die Steuerung besitzt 2 Ntc-Sensoren mit Minimal-/Maximaltemperaturüberwachung und 1 Drucksensor mit entspr. Minimal/Maximaldrucküberwachung und 2 Relais die bei einem Fehler zugeschalten werden können. Wie kann ich nun in der Klasse TSteuerung am besten die Beziehung zwischen Sensor und Aktor konfigurierbar machen. Ich stelle mir eine Art Matrix (Array) vor in der die Fehlerzustände der Sensoren mit den Eingängen der Aktoren verknüft werden können. Damit möchte ich dann mittels GUI zb. den SensNTC[1].MaxError und SensDruck[1].MinError mit Relais[2] und den SensDruck[1].MaxError mit Relais[1] verknüpfen. Das ganze habe ich in der Steuerung momentan mit dynamischen Arrays aufgebaut um flexibel die Anzahl der Sensoren und Aktoren festlegen zu können.

Fragen:
1. Wie verküpfe ich einen Sensor.Alarm mit einm Aktor.Eingang?
2. Sollte man die Sensoren lieber von einer Klasse TSensor ableiten und das Relais von einer Klasse TAktor um dann ein mehrdimensionales Array (TAlarmConfig) zu erstellen? Hier fehlt mir leider noch die zündende Idee bzw. die Erfahrung mit OOP.


Delphi-Quellcode:
type
  TSensNtc = class(Tobject)
  private
    FTmpIs: single;
    FErrMin: boolean;
    FErrMax: boolean;
    FLimitMax: smallint;
    FLimitMin: smallint;
    procedure SetErrMin(const Value: boolean);
    procedure SetErrMax(const Value: boolean);
    procedure SetLimitMax(const Value: smallint);
    procedure SetLimitMin(const Value: smallint);
    procedure SetTmpIst(const Value: single);
  public
    property TmpIst: single read FTmpIs write SetTmpIst; // IsValue
    property ErrMin: boolean read FErrMin write SetErrMin; // IsValue
    property ErrMax: boolean read FErrMax write SetErrMax; // IsValue
    property LimitMax: smallint read FLimitMax write SetLimitMax;
    // SetValue
    property TmpLimitMin: smallint read FLimitMin write SetLimitMin;
    // SetValue
    constructor Create;
    destructor Destroy; override;
  end;

type
  TSensPress = class(Tobject)
  private
    FErrMin: boolean;
    FPressureIst: single;
    FLimitMax: smallint;
    FLimitMin: smallint;
    FErrMax: boolean;
    procedure SetErrMax(const Value: boolean);
    procedure SetErrMin(const Value: boolean);
    procedure SetLimitMax(const Value: smallint);
    procedure SetLimitMin(const Value: smallint);
    procedure SetPressureIst(const Value: single);
  public
    property PressureIst: single read FPressureIst write SetPressureIst;
    // IsValue
    property ErrMin: boolean read FErrMin write SetErrMin; // IsValue
    property ErrMax: boolean read FErrMax write SetErrMax; // IsValue
    property LimitMax: smallint read FLimitMax write SetLimitMax;
    // SetValue
    property LimitMin: smallint read FLimitMin write SetLimitMin;
    // SetValue
    constructor Create;
    destructor Destroy; override;
  end;

type
  TRelay = class(TObject)
  private
    FSetOn: boolean;
    procedure SetSetOn(const Value: boolean);
  public
    property SetOn: boolean read FSetOn write SetSetOn;
  end;

type
  TSteuerung = class(Tobject)
  private
    FSensNtcCount: integer;
    FSensPCount: integer;
    FRelayCount: integer;
    FSensNtc: array of TSensNtc;
    FSensP: array of TSensPress;
    FRelay: array of TRelay;
  public
    constructor Create;
    destructor Destroy; override;
  end;

constructor TSteuerung.Create;
var
  i: integer;
begin
  inherited;
  FSensNtcCount := 2;
  FSensPCount := 3;
  FRelayCount := 2;
  for i := 0 to FSensNtcCount - 1 do
    FSensNtc[i] := TSensNtc.Create;
  for i := 0 to FSensPCount - 1 do
    FSensP[i] := TSensPress.Create;
  for i := 0 to FRelayCount - 1 do
    FRelay[i] := TRelay.Create;
end;
Jan
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.464 Beiträge
 
Delphi 12 Athens
 
#2

AW: Problem mit Klassenerstellung

  Alt 14. Dez 2016, 12:25
Ich würde folgende Strukur vorschlagen:
Delphi-Quellcode:
type
TCustomSensor = class;
TSignalGeber = class;
TSignal = class;
TCustomAktor = class;

// Jeder Sensor liefert erst mal nur einen Messwert und löst ein Ereignis beim SignalGeber aus, wenn sich der Messwert ändert.

TCustomSensor = class()
private
  FSignalGeber: TSignalGeber;
publiv
  property Value: Float;
  property SignalGeber;
end;

// Der Signalgeber reagiert auf das Ereignis eines Sensors. Dazu verfügt er über eine Liste von frei definierten Signalen. Der Signalgeber leited das Ereignis an alle Signale weiter.

TSignalGeber = class()
protected
  FSignalList: TObjectList; // TSignal
puplic
  procedure DoOnSensorChange(Sender: TCustomSensor);
  procedure AddSignal(AItem: TSignal);
  procedure RemoveSignal(AItem: TSignal);
end;

//Das Signal reagiert auf das Ereignis in dem es den Wert des Sensors mit dem hinterlegten Wertebereich vergleicht und den neuen Zustand ermittelt. Ändert sich dabei der Zustand (False/True) meldet es dies dem zugeordneten Aktor.

TSignal = class()
puplic
  procedure DoOnSensorChange(Sender: TCustomSensor);
  property Value: Float;
published
  property MinValue: Float;
  property MaxValue: Float;
  property Aktor: TCustomAktor;
end;

TCustomAktor = class()
puplic
  procedure DoOnSignalChange(Sender: TSignal);
end;
Der Vorteil ist, konkrete Implementierungen müssen nur von TCustomSensor oder TCustomAktor abgeleited werden und sind relativ einfach gehalten. TSignal und TSignalGeber müssen nicht mehr verändert werden, da diese weitgehend frei von Abhängigkeiten implementiert sind. Ein Fehler ist hier auch nur ein frei definiertes Signal, das durch einen Aktor zu verarbeiten ist. Ein Aktor könnte z.B. mit dem Anschalten einer Warnlampe oder einem Protokolleintrag reagieren.
  Mit Zitat antworten Zitat
Smeik

Registriert seit: 21. Mär 2016
Ort: Thüringen
6 Beiträge
 
Delphi 10.1 Berlin Professional
 
#3

AW: Problem mit Klassenerstellung

  Alt 14. Dez 2016, 14:53
Hallo Blup, deine Idee finde ich gut.
Der Signalgeber in Kombination mit dem Signal ist sozusagen das Bindeglied zwischen Sensor und Aktor. Der Aktor sollte ja eigentlich nicht den Sensor kennen und umgekehrt.
Ich werde mal versuchen Sie so umzusetzen.

Danke
Jan
  Mit Zitat antworten Zitat
Smeik

Registriert seit: 21. Mär 2016
Ort: Thüringen
6 Beiträge
 
Delphi 10.1 Berlin Professional
 
#4

AW: Problem mit Klassenerstellung

  Alt 15. Dez 2016, 11:08
Ich habe deinen Vorschlag mal umgesetzt und er funktioniert sehr gut. Jetzt wollte ich die verschiedenen Klassen in einzelnen Units (uSiganl, uAktor, uSensor) auslagern und habe das Problem der zirkulären Unit-Referenzen. Meine Idee war eine unit uSignal zu erstellen in der zum einem TSignal und davon abgeleitet TSignalMax TSignalMin und weitere stehen. Das selbe mit TSensor (TSensorNtc, ...) und mit TAktor (TAktorRelay, TAktorLed). Das hat leider so nicht geklappt.
Sollte ich lieber die drei Urklassen TSignal, TCustomSensor, TCustomAktor und TSignalgeber in einer Unit stehen lassen und die Ableitung der Urklassen dann in einzelne Units auslagern? Was wäre hier der richtige Weg?
Jan
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.464 Beiträge
 
Delphi 12 Athens
 
#5

AW: Problem mit Klassenerstellung

  Alt 15. Dez 2016, 21:35
Es handelt sich um weitgehend abstrakte Basisklassen, die in enger Beziehung zueinander stehn. Ich würde alle zusammen in einer Unit lassen. Die Implementierung eines konkreten Sensors oder Aktors gehört dagegen in eine eigene Unit, die je nach technischer Umsetzung wieder andere Abhängigkeiten hat.
  Mit Zitat antworten Zitat
IYuky

Registriert seit: 29. Jan 2016
14 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: Problem mit Klassenerstellung

  Alt 20. Dez 2016, 09:17
Ich würde noch vorschlagen mit Interfaces zu arbeiten
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#7

AW: Problem mit Klassenerstellung

  Alt 20. Dez 2016, 22:08
... und habe das Problem der zirkulären Unit-Referenzen.
Wo hast Du die Units in der Uses-Anweisung eingetragen?

interface oder implementation?

Das Problem lässt sich oft (aber nicht immer) beheben, wenn man die Uses-Anweisung hinter implementation nutzt.

Units schreib ich eigentlich nur dann hinter interface, wenn sie bereits vor implementation zwingend benötigt werden.

Eventuell hast Du ja damit Glück.
  Mit Zitat antworten Zitat
Antwort Antwort


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 10:33 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