![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
ООП
GanibalLector © (2005-01-25 14:04:00)Имеются классы датчиков давления,температуры и пр. все от TObject.Предположим,выглядят так :
type TTemperatureSensor = class(TObject)
private
FTemperatupe:integer;
public
function GetCurrentTemperature:integer;
Constructor Create(const Temperature:integer);
end;
!!!Необходимо создать класс-коллекцию,котороя будет наполняться из классов датчиков,а также,чтобы она могла вызывать МЕТОДЫ
из классов датчиков.Т.е. "устройсво1" состоит из датчика температуры и давления."устройсво2" состоит из двух датчиков температуры.
Вопрос.Каким образом это сделать?
Поглядев на книгу Буча,вижу что можно создать класс "устройсв" от TCollection.Но,блин,прийдется еще использовать TCollectionitem.И как это все связать я не знаю.
И,второй вариант,Jack128 предложил.Создать класс-коллекцию от TObjectList.Создал,все чудесно наполняется,изменяется и удаляется.
НО!!!Мне необходимо вызывать методы классов датчиков.
Т.е.если TTemperatureSensor имел метод GetCurrentTemperature ,то мне нужно прямо из класса"устройств" вызвать его метод.
Делаю примерно так :
var Q:TSensor;
begin
Q:=TSensor.Create;
Q.Add(TTemperatureSensor.Create(100));
Q.Add(TPressureSensor.Create);
Caption:=inttostr((Q.Items[0] as TTemperatureSensor).GetCurrentTemperature); // до фени
Можно конечно сделать так:
Q:=TSensor.Create;
QQ:=TTemperatureSensor.Create(100);
Q.Add(QQ);
Caption:=inttostr(QQ.GetCurrentTemperature);
...
но я так не хочу.Ибо "устройств" много,а "датчиков" еще больше.И носиться с переменными уж больно не хочется.
Какие будут мысли?
GanibalLector (2005-01-25 19:45:00) [1]Всем спасибо.
REA (2005-01-25 17:32:00) [2]Типа такого:
Type
TNetworkItemOption = ( niAllowFind, niAllowCheck, niAllowSetup,
niAllowAttach, niAllowDetach, niAllowCalibration,
niHidden );
TNetworkItemOptions = Set Of TNetworkItemOption;
TNetworkItemState = Set Of (nsError, nsWarning);
TNetworkItem = Class;
TGSServer = Class;
TGSNode = Class;
TGSSensor = Class;
TNetworkItemClass = Class Of TNetworkItem;
TNetworkItem = Class(TPersistent)
Private
FList: TObjectList;
FState: TNetworkItemState;
Function GetServer: TGSServer;
Function GetNode: TGSNode;
Function GetSensor(GID: Integer): TGSSensor;
Protected
FAddress: String; // Item address
FID: Integer; // Item ID
FItemID: Integer; // Tree ID
FInitData: String;// Init data
FName: String; // Item name
FOptions: TNetworkItemOptions;
FParent: TNetworkItem;
Procedure Detach(Item: TNetworkItem); virtual; // Unregister in database and free
Procedure Attach(ParentItem, Item: TNetworkItem); overload; virtual;
Procedure Attach(Item: TNetworkItem); overload; virtual; // Register in database and add to list
Function GetOptions: TNetworkItemOptions; virtual;
Function QueryAttachItem: TNetworkItem; virtual; // Query attach something
Function Setup(Item: TNetworkItem): Boolean; virtual;
Public
Constructor Create; overload; virtual;
Constructor Create(Const Name, Address, InitData: String; ID: Integer; ItemID: Integer); overload; virtual;
Constructor Create(Const Name, Address, InitData: String; ID: Integer = 0); overload; virtual;
Destructor Destroy; override;
Class Function GetMetaClass(Const aClassName: String): TNetworkItemClass;// Load package if needed
Procedure AddItem(Item: TNetworkItem);
Procedure Calibrate; virtual;
Procedure Check; virtual;
Function Find: Boolean; virtual;
Function IsParentOf(Item: TNetworkItem): Boolean;
Procedure Notify(Event: TServiceEvent; Sender: TObject=Nil); virtual;
Procedure Save; // Update database information
Property Address: String Read FAddress;
Property ID: Integer Read FID;
Property InitData: String Read FInitData;
Property ItemID: Integer Read FItemID;
Property Items: TObjectList Read FList;
Property Name: String Read FName Write FName;
Property Node: TGSNode Read GetNode;
Property Options: TNetworkItemOptions Read GetOptions;
Property Parent: TNetworkItem Read FParent;
Property Sensor[GID: Integer]: TGSSensor Read GetSensor;
Property Server: TGSServer Read GetServer;
Property State: TNetworkItemState Read FState Write FState;
End;
TGSServerFlags = Set of (sfPrimary, sfNoTimer);
TGSServer = Class(TNetworkItem)
Private
FLogging: Boolean;
Function GetConnected: Boolean; virtual; abstract;
Function GetScanRate: Integer;
Procedure SetScanRate(Const Value: Integer);
Protected
Procedure SetLogging(Const Value: Boolean); virtual;
{ Procedure HardwareReset;
SyncronizeTimers}
Procedure PrepareLogging; virtual; abstract;
Public
Procedure Down; virtual; abstract;
Function IsUp: Boolean; virtual; abstract;
Procedure Up; virtual; abstract;
Property Connected: Boolean Read GetConnected;
Property Logging: Boolean Read FLogging Write SetLogging;
Property ScanRate: Integer Read GetScanRate Write SetScanRate;
End;
TGSNode = Class(TNetworkItem)
End;
TGSDevice = Class(TNetworkItem)
End;
TQueryClbrDataProc = Function: Double;
TGSSensor = Class(TNetworkItem)
Protected
FClbrObject: TObject; // Calibration data pointer
Public
Constructor Create(Const Name, Address, InitData: String; ID: Integer); override;
Procedure Calibrate; override;
Function CodeToValue(Code: Double): Double; virtual;
Function GetData: Double; virtual; abstract;
Property CalibrationObject: TObject Read FClbrObject;
End;
TGSServerClass = Class Of TGSServer;
TGSNetwork = Class(TNetworkItem)
Private
FLogging: Boolean;
FOnChanged: TNotifyEvent;
FOnDataChanged: TNotifyEvent;
Procedure SetLogging(const Value: Boolean);
Procedure SetServersLogging(const Value: Boolean);
Procedure LoadItems(ParentItem: TNetworkItem);
Public
Constructor Create; override;
Destructor Destroy; override;
Procedure AttachTo(Item: TNetworkItem);
Procedure Changed;
Procedure DataChanged;
Procedure Detach(Item: TNetworkItem); override;
Function Setup(Item: TNetworkItem): Boolean; override;
Procedure UpServers;
Property Logging: Boolean Read FLogging Write SetLogging;
Property OnChanged: TNotifyEvent Read FOnChanged Write FOnChanged;
Property OnDataChanged: TNotifyEvent Read FOnDataChanged Write FOnDataChanged;
End;
Arm79 (2005-01-25 16:24:00) [3]Возможно. Спорить с человеком с голубым значком себе дороже :). Особенно если он прав 8).
Мое решение навеяно тем проектом, которым сейчас занимаюсь. Там в функции и процедуры передаются нетипизированные константы. И мне пришлось выносить анализ этих констант в отдельную процедуру.
jack128 (2005-01-25 15:49:00) [4]GanibalLector © (25.01.05 14:04)
Т.е. "устройсво1" состоит из датчика температуры и давления."устройсво2" состоит из двух датчиков температуры.
При таком определении устройства(у тя устройство - это совокупность нескольких строго заданных и не меняющихся со временем датчиков) о TSensors вообще парится не нужно. Это лишь вспомогательный класс..
type
TSensor = class
public
property Value: Double;
end;
TTemperatureSensor = class(TSenser);
TPressureSensor = class(TSensor);
TDevice = class
public
function GetSensor(index: Integer): TSensor; virtual; abstract;
function GetSensorCount: Integer; virtual; abstract;
end;
TDevice1 = class(TDevice)
public
function GetSensor(index: Integer): TSensor; override;
function GetSensorCount: Integer; override;
function TemperatuteSensor: TTemperatureSensor;
function PressureSensor: TPressureSensor;
end;
TDevice2 = class(TDevice)
public
function GetSensor(index: Integer): TSensor; override;
function GetSensorCount: Integer; override;
function TemperatuteSensor1: TTemperatureSensor;
function TemperatuteSensor2: TTemperatureSensor;
end;
Вот если бы клиент сам мог собирать "устройства" из датчиков, то тогда имело бы смысл создать у TDevice свойство Sensors: TSensorList {твой наследник от TObjectList}
Arm79 © (25.01.05 15:40) [11]
Это же я и предлагал в Arm79 © (25.01.05 14:13) [1].
нет, не совсем. Ты просто вынес преобразование типов в отдельный метод, это конечно лудше чем у автора, но все рано не супер.. А если сделать так как предлагает Ега или я, то можно обойтись вообще без преобразования.
Ega23 (2005-01-25 15:46:00) [5]Интерфейсы просто как вариант.
В мозгу картинку увиделinterface as variant.
Пора домой...
Arm79 (2005-01-25 15:40:00) [6]я и не парился. Это же я и предлагал в Arm79 © (25.01.05 14:13) [1]. Интерфейсы просто как вариант.
jack128 (2005-01-25 15:24:00) [7]Arm79 © (25.01.05 14:54) [8]
в данном случае можнно не париться с интерфейсами..
type
TSensor = class
public
property Value: Double;
end;
TTemperatureSensor = class(TSenser);
TPressureSenser = class(TSensor);
Ega23 (2005-01-25 15:23:00) [8]
type
TSensor(TObject)
private
public
function GetSensorValue:Variant; virtual; abstract;
end;
TTemperatureSensor(TSensor)
private
public
function GetSensorValue:Variant; override;
end;
TPressureSensor(TSensor)
private
public
function GetSensorValue:Variant; override;
end;
TDevice(TObject)
private
FItems:TObjectList;
function GetItemByIndex(Index: Integer): TSensor;
public
property Items[Index:Integer]:TSensor Read GetItemByIndex;
end;
Я бы что-то в таком духе наваял...
Arm79 (2005-01-25 14:54:00) [9]Схематично:
type
ISensor = interface
['{808A95E8-AAD1-4D6E-920A-8A599DC8FD75}'] // Ctrl+Shift+G
function GetValue : Variant;
end;
TSensorTemp = class(TInterfacedObject, ISensor)
public
function GetCurrentTemp: Integer;
function GetValue: Variant;
end;
TSensorPress = class(TInterfacedObject, ISensor)
public
function GetCurrentPress: Integer;
function GetValue: Variant;
end;
...
function TSensorTemp.GetValue;
begin
Result := GetCurrentTemp;
end;
function TSensorTemp.GetValue;
begin
Result := GetCurrentPress;
end;
...
var
Value : Variant;
iS : ISensor;
lsS: TObjectList; // к примеру
begin
...
iS := lsS.objects[i]; // что то в этом роде. набираю от руки, не проверить
Value := iS.GetValue;
...
end;
GanibalLector (2005-01-25 14:48:00) [10]>Может быть сделать все датчики наследником от типа TDatchick?
И что это изменит?
TUser (2005-01-25 14:46:00) [11]Может быть сделать все датчики наследником от типа TDatchick?
GanibalLector (2005-01-25 14:43:00) [12]>А какая предметная область?
Да никакой.Это я из Буча взял.
А можно ли взглянуть на Ваши классы цифровых датчиков...чисто в учебных целях.
Спасибо,кстати.
REA (2005-01-25 14:39:00) [13]А какая предметная область? У меня есть классы для сети цифровых датчиков.
>Создать класс-коллекцию от TObjectList.Создал,все чудесно наполняется,изменяется и удаляется. НО!!!Мне необходимо вызывать методы классов датчиков.
Абсолютно тоже самое:
If List.Items[i] is TTemperatureSensor Then
SomeTemp := TTemperatureSensor(List.Items[i]).GetCurrentTemperature;
GanibalLector (2005-01-25 14:36:00) [14]>или, как вариант, прикрутить все классы датчиков к одному интерфейсу
Это как ?
Arm79 (2005-01-25 14:34:00) [15]или, как вариант, прикрутить все классы датчиков к одному интерфейсу
Arm79 (2005-01-25 14:13:00) [16]а так к примеру нельзя?
type
TSensorType = (stTemperature, stPress, stUnknown);
...
type
TCommonSensor = class (TObject)
private
FType : TSensorType;
public
function GetValue: Variant;
end;
...
function TCommonSensor.GetValue: Variant;
begin
case FType of
stTemperature: Value := (Self as TTemperatureSensor).GetCurrentTemperature;
stPress: Value := (Self as TPressSensor).GetCurrentPress;
else
raise Exception.Create('Unknown sensor type! function TCommonSensor.GetValue')
end;
end;