|
Вопрос # 4 819/ вопрос открыт / |
|
Здравствуйте, товарищи эксперты!
пишу open-source шифрованный форум, который будет выполняться на машинах клиентов и обмениваться зашифрованными ассиметричным шифрованием пакетами по электронной почте.
использую SQLite
вопрос стоит о идеологически верной организации процедур записи и чтения в базу
Приложение: Переключить в обычный режим-
- {{code}}
- TMessage = class (TObject)
- private
- f_ID: TID;
- protected
- function GetID : TID;
- procedure SetID (const aValue: TID) : TID;
- class function _GetID (const aValue: TID) : TID;
- class function _SetID (const aValue: TID) : TID;
- public
- property ID: TID read GetID write SetID default 0;
- end;
- {{/code}}
-
-
-
 |
Вопрос задал: mirt.steelwater (статус: Посетитель)
Вопрос отправлен: 14 декабря 2010, 15:50
Состояние вопроса: открыт, ответов: 0.
|
Мини-форум вопроса
Всего сообщений: 19; последнее сообщение — 16 декабря 2010, 14:00; участников в обсуждении: 2.
|
Вадим К (статус: Академик), 14 декабря 2010, 17:17 [#1]:
вот тут точно не ошибка?
procedure SetID (const aValue: TID) : TID;
непонятно назначение методов
class function _GetID (const aValue: TID) : TID;
class function _SetID (const aValue: TID) : TID;
Галочка "подтверждения прочтения" - вселенское зло.
|
|
mirt.steelwater (статус: Посетитель), 14 декабря 2010, 18:27 [#2]:
ну да - я опечатался, процедура не возвращает тип, конечно
procedure SetID (const aValue: TID);
Ⓐ свобода сопротивление солидарность
|
|
mirt.steelwater (статус: Посетитель), 14 декабря 2010, 18:31 [#3]:
методы класса _GetID и _SetID нужны для того, чтобы приводить значения свойства в значения полей без создания экземпляра объекта в функциях класса этого объекта - вернусь домой, я приложу весь код.
там что-то вроде такого:
class procedure TMessage.Delete (aDB: TDataBase; const anID: TID);
begin
query := Format ('DELETE FROM messages WHERE id="%d"',
[ _SetID (anID) ]);
end;
Ⓐ свобода сопротивление солидарность
|
|
Вадим К (статус: Академик), 15 декабря 2010, 11:15 [#4]:
Цитата:
методы класса _GetID и _SetID нужны для того, чтобы приводить значения свойства в значения полей без создания экземпляра объекта в функциях класса этого объекта - вернусь домой, я приложу весь код.
спрашивается - а смысл??? почему нельзя воспользоваться предыдущими методами? Или для других значений? тогда это ещё может быть как то оправдано. Но не сильно
То есть, у Вас в классе есть дубликаты? тогда это можно попробовать решить одним общим наследником. разберем на примере _SetID и SetID.
Как бы Вы не писали код, для этих методов возможно пять вариантов:
- у каждой свой уникальный код. Это плохо. потому что нужно следить за идентичностью методов.
- они являются точной копией друг дружки, за небольшими исключениями. Это не лучше первого варианта.
- оба эти метода вызывают какой то один метод/функцию. Это уже лучше. значительно лучше, но есть ещё излишество.
- классовый метод вызывает неклассовый. Все хорошо, кроме одного - придется создавать объект, а Вы этого не хотите.
- неклассовый метод вызывает классовый метод. Это уже достаточно хорошо. Где то так
procedure TMessage.SetID (const aValue: TID) : TID;
begin
_SetID(aValue);
end;
class procedure TMessage._SetID (const aValue: TID);
begin
// а тут код преобразования.
end;
Согласитесь - это уже сильно упрощает написание. Но как не хочется каждый раз писать. Поэтому пишем базовый класс, который заключит в себя часть функционала.
TBase = class (TObject)
private
f_ID: TID;
protected
function GetID : TID; virtual;
procedure SetID (const aValue: TID) ; virtual;
class function _GetID (const aValue: TID) : TID; Virtual; Abstract;
class procedure _SetID (const aValue: TID); Virtual; Abstract;
public
property ID: TID read GetID write SetID default 0;
end;
////
procedure TBase.SetID (const aValue: TID) : TID;
begin
_SetID(aValue);
end;
function TBase.GetID : TID;
begin
result := _GetID;
end;
( я не обещаю, что этот код заработает в 7 делфи и младше, а вот в 2005 и старше должно).
Теперь, когда нужно создать новый класс, просто делается так
type
TMessage = class(TBase)
protected
class function _GetID (const aValue: TID) : TID; override;
class procedure _SetID (const aValue: TID); override;
end;
////
class function TMessage._GetID (const aValue: TID) : TID; abstract;
begin
// реализация
end;
class procedure TMessage._SetID (const aValue: TID); abstract;
begin
// реализация
end;
Итого, что получается. Два метода написать мы никогда не забудем - их и не нужно писать - они уже есть. Свойство также всегда есть. А два других метода нам не даст забыть компилятор - там есть ключевое слово abstract, которое будет требовать реализацию этого метода. То есть, сплошной плюс.
Что же делать, если в каком то из наследников потребуется неклассовые методы доступа написать как то по особому? никаких проблем. Возле них недаром в базовом классе написано virtual. Поэтому, если нужно нестандартное поведение, мы просто его реализуем, не забывая добавить слово override;
Но тут ещё один скрытый плюс, который сразу не рассмотреть. Пускай, нам нужно держать объекты в TList (грубо говоря - в массиве). Так как они будут иметь одного предка, можно писать более простой код для массовых операций.
P.S. у меня нет возможности проверить этот код. Но идеологически он верен. Скорее всего его придется хорошо доработать напильником под Ваши нужды.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
mirt.steelwater (статус: Посетитель), 16 декабря 2010, 11:22 [#5]:
да ведь я так и сделал
проблема только в том, что единственное что я могу определить в базовом классе - это именно операции с идентификатором
а все остальные свойства сущностей в потомках отличаются - и приходится писать 2 метода объекта вызывающих по возможности методы класса. и 2 метода класса, которые стараются не прибегать к созданию временного экземпляра.
Ⓐ свобода сопротивление солидарность
|
|
mirt.steelwater (статус: Посетитель), 16 декабря 2010, 11:22 [#6]:
{ ñîîáùåíèå }
{$M+}
CMessage = class of TMessage;
PMessage = ^TMessage;
TMessage = class (TObject)
private
f_DB: TSQLiteDatabase; { îáúåêò áàçû
äàííûõ }
f_ID: TID; { óíèêàëüíûé
èäåíòèôèêàòîð }
f_TimeStampCreate: DWORD; { äàòà è âðåìÿ
ñîçäàíèÿ }
f_TimeStampModify: DWORD; { äàòà è âðåìÿ
èçìåíåíèÿ }
f_TimeStampPublic: DWORD; { äàòà è âðåìÿ
îòïðàâêè }
f_CategorieID: TID; {
èäåíòèôèêàòîð
êàòåãîðèè, â êîòîðîé
ðàçìåùåíî ñîîáùåíèå }
f_Categorie: TCategorie; { îáúåêò
êàòåãîðèè, â êîòîðîé
ðàçìåùåíî ñîîáùåíèå }
f_MessageTypeID: TID; {
èäåíòèôèêàòîð òèïà
ñîîáùåíèÿ }
f_MessageType: TMessageType; { îáúåêò òèïà
ñîîáùåíèÿ }
f_MessageStatusID: TID; {
èäåíòèôèêàòîð
ñòàòóñà ñîîáùåíèÿ }
f_MessageStatus: TMessageStatus; { îáúåêò
ñòàòóñà ñîîáùåíèÿ }
f_AuthorID: TID; {
èäåíòèôèêàòîð àâòîðà
ñîîáùåíèÿ }
f_Author: TOperator; { àâòîð
ñîîáùåíèÿ }
f_Subject: String; { òåìà }
f_Text: String; { òåêñò }
f_Version: TVERSION_INFO; { âåðñèÿ
ñîîáùåíèÿ }
protected
function GetID : TID;
function GetTimeStampCreate : TDateTime;
function GetTimeStampModify : TDateTime;
function GetTimeStampPublic : TDateTime;
function GetCategorieID : TID;
function GetCategorie : TCategorie;
function GetMessageTypeID : TID;
function GetMessageType : TMessageType;
function GetMessageStatusID : TID;
function GetMessageStatus : TMessageStatus;
function GetAuthorID : TID;
function GetAuthor : TOperator;
function GetSubject : String;
function GetText : String;
function GetVersion : TVERSION_INFO;
function GetHash : String;
procedure SetID (const aValue: TID);
procedure SetTimeStampCreate (const aValue: TDateTime);
procedure SetTimeStampModify (const aValue: TDateTime);
procedure SetTimeStampPublic (const aValue: TDateTime);
procedure SetCategorieID (const aValue: TID);
procedure SetCategorie (const aValue: TCategorie);
procedure SetMessageTypeID (const aValue: TID);
procedure SetMessageType (const aValue: TMessageType);
procedure SetMessageStatusID (const aValue: TID);
procedure SetMessageStatus (const aValue: TMessageStatus);
procedure SetAuthorID (const aValue: TID);
procedure SetAuthor (const aValue: TOperator);
procedure SetSubject (const aValue: String);
procedure SetText (const aValue: String);
procedure SetVersion (const aValue: TVERSION_INFO);
class function _GetID (const aValue: TID) : TID;
class function _GetTimeStampCreate (const aValue: DWORD) : TDateTime;
class function _GetTimeStampModify (const aValue: DWORD) : TDateTime;
class function _GetTimeStampPublic (const aValue: DWORD) : TDateTime;
class function _GetCategorieID (const aValue: TID) : TID;
class function _GetCategorie (const aValue: TCategorie) : TCategorie;
class function _GetMessageTypeID (const aValue: TID) : TID;
class function _GetMessageType (const aValue: TMessageType) : TMessageType;
class function _GetMessageStatusID (const aValue: TID) : TID;
class function _GetMessageStatus (const aValue: TMessageStatus) : TMessageStatus;
class function _GetAuthorID (const aValue: TID) : TID;
class function _GetAuthor (const aValue: TOperator) : TOperator;
class function _GetSubject (const aValue: String) : String;
class function _GetText (const aValue: String) : String;
class function _GetVersion (const aValue: TVERSION_INFO) : TVERSION_INFO;
class function _SetID (const aValue: TID) : TID;
class function _SetTimeStampCreate (const aValue: TDateTime) : DWORD;
class function _SetTimeStampModify (const aValue: TDateTime) : DWORD;
class function _SetTimeStampPublic (const aValue: TDateTime) : DWORD;
class function _SetCategorieID (const aValue: TID) : TID;
class function _SetCategorie (const aValue: TCategorie) : TCategorie;
class function _SetMessageTypeID (const aValue: TID) : TID;
class function _SetMessageType (const aValue: TMessageType) : TMessageType;
class function _SetMessageStatusID (const aValue: TID) : TID;
class function _SetMessageStatus (const aValue: TMessageStatus) : TMessageStatus;
class function _SetAuthorID (const aValue: TID) : TID;
class function _SetAuthor (const aValue: TOperator) : TOperator;
class function _SetSubject (const aValue: String) : String;
class function _SetText (const aValue: String) : String;
class function _SetVersion (const aValue: TVERSION_INFO) : TVERSION_INFO;
public
constructor Create (DB: TSQLiteDatabase; anArgs: array of const); overload;
constructor Create (DB: TSQLiteDatabase; anArgs: array of const; aVersion: TVERSION_INFO); overload;
constructor Create (DB: TSQLiteDatabase; anArgs: array of const; aVersion: array of const); overload;
destructor Destroy; override;
class function Load (DB: TSQLiteDatabase; const anID: TID) : TMessage; overload;
procedure Load; overload;
class function Find (DB: TSQLiteDatabase; const aHash: String) : TID;
class function Save (DB: TSQLiteDatabase; anArgs: array of const) : TID; overload;
procedure Save; overload;
class procedure Delete (DB: TSQLiteDatabase; const anID: TID); overload;
procedure Delete; overload;
class procedure DeleteOnType (DB: TSQLiteDatabase; const aTypeID: TID); overload;
class procedure DeleteOnType (DB: TSQLiteDatabase; const aTypeName: String); overload;
class procedure DeleteOnStatus (DB: TSQLiteDatabase; const aStatusID: TID); overload;
class procedure DeleteOnStatus (DB: TSQLiteDatabase; const aStatusName: String); overload;
class procedure DeleteOnAuthor (DB: TSQLiteDatabase; const anAuthorID: TID); overload;
class procedure DeleteOnAuthor (DB: TSQLiteDatabase; const anAuthorName: String); overload;
class procedure DeleteAll (DB: TSQLiteDatabase; const aCategorieID: TID);
property ID: TID read GetID write SetID default 0;
property TimeStampCreate: TDateTime read GetTimeStampCreate write SetTimeStampCreate;
property TimeStampModify: TDateTime read GetTimeStampModify write SetTimeStampModify;
property TimeStampPublic: TDateTime read GetTimeStampPublic write SetTimeStampPublic;
property CategorieID: TID read GetCategorieID write SetCategorieID default 0;
property Categorie: TCategorie read GetCategorie write SetCategorie;
property MessageTypeID: TID read GetMessageTypeID write SetMessageTypeID default 0;
property MessageType: TMessageType read GetMessageType write SetMessageType;
property MessageStatusID: TID read GetMessageStatusID write SetMessageStatusID default 0;
property MessageStatus: TMessageStatus read GetMessageStatus write SetMessageStatus;
property AuthorID: TID read GetAuthorID write SetAuthorID default 0;
property Author: TOperator read GetAuthor write SetAuthor;
property Subject: String read GetSubject write SetSubject;
property Text: String read GetText write SetText;
property Version: TVERSION_INFO read GetVersion write SetVersion;
property Hash: String read GetHash;
end;
{$M-}
Ⓐ свобода сопротивление солидарность
|
|
mirt.steelwater (статус: Посетитель), 16 декабря 2010, 11:23 [#7]:
{ êàòåãîðèÿ }
{$M+}
CCategorie = class of TCategorie;
PCategorie = ^TCategorie;
TCategorie = class (TObject)
private
f_DB: TSQLiteDatabase; { îáúåêò áàçû
äàííûõ }
f_ID: TID; { óíèêàëüíûé
èäåíòèôèêàòîð }
f_ParentID: TID; {
èäåíòèôèêàòîð ïðåäêà
â ëîãè÷åñêîì äåðåâå
êàòåãîðèé }
f_Parent: TCategorie; { ññûëêà íà
ïðåäêà â ëîãè÷åñêîì
äåðåâå êàòåãîðèé }
f_TimeStampCreate: DWORD; { äàòà è âðåìÿ
ñîçäàíèÿ }
f_TimeStampModify: DWORD; { äàòà è âðåìÿ
èçìåíåíèÿ }
f_TimeStampPublic: DWORD; { äàòà è âðåìÿ
îòïðàâêè }
f_CategorieTypeID: TID; {
èäåíòèôèêàòîð òèïà
êàòåãîðèè }
f_CategorieType: TCategorieType; { îáúåêò òèïà
êàòåãîðèè }
f_CategorieStatusID: TID; {
èäåíòèôèêàòîð
ñòàòóñà êàòåãîðèè }
f_CategorieStatus: TCategorieStatus; { îáúåêò
ñòàòóñà êàòåãîðèè }
f_AuthorID: TID; {
èäåíòèôèêàòîð àâòîðà
êàòåãîðèè }
f_Author: TOperator; { àâòîð
êàòåãîðèè }
f_Name: String; { íàçâàíèå }
f_Description: String; { îïèñàíèå }
f_Version: TVERSION_INFO; { âåðñèÿ
êàòåãîðèè }
protected
function GetID : TID;
function GetParentID : TID;
function GetParent : TCategorie;
function GetTimeStampCreate : TDateTime;
function GetTimeStampModify : TDateTime;
function GetTimeStampPublic : TDateTime;
function GetCategorieTypeID : TID;
function GetCategorieType : TCategorieType;
function GetCategorieStatusID : TID;
function GetCategorieStatus : TCategorieStatus;
function GetAuthorID : TID;
function GetAuthor : TOperator;
function GetName : String;
function GetDescription : String;
function GetVersion : TVERSION_INFO;
function GetHash : String;
procedure SetID (const aValue: TID);
procedure SetParentID (const aValue: TID);
procedure SetParent (const aValue: TCategorie);
procedure SetTimeStampCreate (const aValue: TDateTime);
procedure SetTimeStampModify (const aValue: TDateTime);
procedure SetTimeStampPublic (const aValue: TDateTime);
procedure SetCategorieTypeID (const aValue: TID);
procedure SetCategorieType (const aValue: TCategorieType);
procedure SetCategorieStatusID (const aValue: TID);
procedure SetCategorieStatus (const aValue: TCategorieStatus);
procedure SetAuthorID (const aValue: TID);
procedure SetAuthor (const aValue: TOperator);
procedure SetName (const aValue: String);
procedure SetDescription (const aValue: String);
procedure SetVersion (const aValue: TVERSION_INFO);
class function _GetID (const aValue: TID) : TID;
class function _GetParentID (const aValue: TID) : TID;
class function _GetParent (const aValue: TCategorie) : TCategorie;
class function _GetTimeStampCreate (const aValue: DWORD) : TDateTime;
class function _GetTimeStampModify (const aValue: DWORD) : TDateTime;
class function _GetTimeStampPublic (const aValue: DWORD) : TDateTime;
class function _GetCategorieTypeID (const aValue: TID) : TID;
class function _GetCategorieType (const aValue: TCategorieType) : TCategorieType;
class function _GetCategorieStatusID (const aValue: TID) : TID;
class function _GetCategorieStatus (const aValue: TCategorieStatus) : TCategorieStatus;
class function _GetAuthorID (const aValue: TID) : TID;
class function _GetAuthor (const aValue: TOperator) : TOperator;
class function _GetName (const aValue: String) : String;
class function _GetDescription (const aValue: String) : String;
class function _GetVersion (const aValue: TVERSION_INFO) : TVERSION_INFO;
class function _SetID (const aValue: TID) : TID;
class function _SetParentID (const aValue: TID) : TID;
class function _SetParent (const aValue: TCategorie) : TCategorie;
class function _SetTimeStampCreate (const aValue: TDateTime) : DWORD;
class function _SetTimeStampModify (const aValue: TDateTime) : DWORD;
class function _SetTimeStampPublic (const aValue: TDateTime) : DWORD;
class function _SetCategorieTypeID (const aValue: TID) : TID;
class function _SetCategorieType (const aValue: TCategorieType) : TCategorieType;
class function _SetCategorieStatusID (const aValue: TID) : TID;
class function _SetCategorieStatus (const aValue: TCategorieStatus) : TCategorieStatus;
class function _SetAuthorID (const aValue: TID) : TID;
class function _SetAuthor (const aValue: TOperator) : TOperator;
class function _SetName (const aValue: String) : String;
class function _SetDescription (const aValue: String) : String;
class function _SetVersion (const aValue: TVERSION_INFO) : TVERSION_INFO;
public
constructor Create (DB: TSQLiteDatabase; anArgs: array of const); overload;
constructor Create (DB: TSQLiteDatabase; anArgs: array of const; aVersion: TVERSION_INFO); overload;
constructor Create (DB: TSQLiteDatabase; anArgs: array of const; aVersion: array of const); overload;
destructor Destroy; override;
class function Load (DB: TSQLiteDatabase; const anID: TID) : TCategorie; overload;
procedure Load; overload;
class function Find (DB: TSQLiteDatabase; const aHash: String) : TID;
class function Save (DB: TSQLiteDatabase; anArgs: array of const) : TID; overload;
procedure Save; overload;
class procedure Delete (DB: TSQLiteDatabase; const anID: TID); overload;
procedure Delete; overload;
class procedure DeleteOnType (DB: TSQLiteDatabase; const aTypeID: TID); overload;
class procedure DeleteOnType (DB: TSQLiteDatabase; const aTypeName: String); overload;
class procedure DeleteOnStatus (DB: TSQLiteDatabase; const aStatusID: TID); overload;
class procedure DeleteOnStatus (DB: TSQLiteDatabase; const aStatusName: String); overload;
class procedure DeleteOnAuthor (DB: TSQLiteDatabase; const anAuthorID: TID); overload;
class procedure DeleteOnAuthor (DB: TSQLiteDatabase; const anAuthorName: String); overload;
class procedure DeleteAll (DB: TSQLiteDatabase; const aParentID: TID);
property ID: TID read GetID write SetID default 0;
property ParentID: TID read GetParentID write SetParentID default 0;
property Parent: TCategorie read GetParent write SetParent;
property TimeStampCreate: TDateTime read GetTimeStampCreate write SetTimeStampCreate;
property TimeStampModify: TDateTime read GetTimeStampModify write SetTimeStampModify;
property TimeStampPublic: TDateTime read GetTimeStampPublic write SetTimeStampPublic;
property CategorieTypeID: TID read GetCategorieTypeID write SetCategorieTypeID default 0;
property CategorieType: TCategorieType read GetCategorieType write SetCategorieType;
property CategorieStatusID: TID read GetCategorieStatusID write SetCategorieStatusID default 0;
property CategorieStatus: TCategorieStatus read GetCategorieStatus write SetCategorieStatus;
property AuthorID: TID read GetAuthorID write SetAuthorID default 0;
property Author: TOperator read GetAuthor write SetAuthor;
property Name: String read GetName write SetName;
property Description: String read GetDescription write SetDescription;
property Version: TVERSION_INFO read GetVersion write SetVersion;
property Hash: String read GetHash;
end;
{$M-}
Ⓐ свобода сопротивление солидарность
|
|
mirt.steelwater (статус: Посетитель), 16 декабря 2010, 11:23 [#8]:
как видим за исключением лишь некоторых - свойства не повторяются в классах, описывающих хранимые сущности. и таких классов достаточно много, нет никакого однозначно переходящего всюду параметра, кроме ID. определять все свойства всех классов в базовом неправильно, т.к. это даст доступ из потомков к несуществующим свойствам их сущности.
можно, конечно, определить в общем предке только методы
_GetX, _SetX, GetX, SetX
а в наследниках определять свойства с вызовом соотв. методов и при необходимости их переопределять, но я не уверен, что это правильно - тогда нарушается логическая связь "потомственности" и приводит к "вырождению" потомков в сущности большей общности, чем предок..
Ⓐ свобода сопротивление солидарность
|
|
mirt.steelwater (статус: Посетитель), 16 декабря 2010, 11:29 [#9]:
а методы объекта у меня вызывают методы класса - это понятно..
function TMessage.GetTimeStampCreate : TDateTime;
begin
Result := 0.0;
try
Result := _GetTimeStampCreate (f_TimeStampCreate);
except on E: Exception do
raise EClass.Create ([self,'GetTimeStampCreate',ERR_TMESSAGE_GET_TIME_STAMP_CREATE,E],
['{6DC3684E-2866-4B9B-9441-3EDCB0A1E15A}']);
end;
end;
procedure TMessage.SetTimeStampCreate (const aValue: TDateTime);
begin
try
f_TimeStampCreate := _SetTimeStampCreate (aValue);
except on E: Exception do
raise EClass.Create ([self,'SetTimeStampCreate',ERR_TMESSAGE_SET_TIME_STAMP_CREATE,E],
['{0BF909DD-57DA-4DA0-AF5C-2B8A3F287866}']);
end;
end;
class function TMessage._GetTimeStampCreate (const aValue: DWORD) : TDateTime;
begin
Result := 0.0;
try
if ( aValue > 0 ) then
Result := UnixToDateTime (aValue)
{else
raise Exception.Create (ERR_TMESSAGE_INCORRECT_TIME_STAMP_CREATE)};
except on E: Exception do
raise EClass.Create ([self,'_GetTimeStampCreate',ERR_TMESSAGE_GET_TIME_STAMP_CREATE,E],
['{777770B1-1D4E-4136-84B7-E2C6783E34C2}']);
end;
end;
class function TMessage._SetTimeStampCreate (const aValue: TDateTime) : DWORD;
begin
Result := 0;
try
if ( aValue > 0 ) then
Result := DateTimeToUnix (aValue)
{else
raise Exception.Create (ERR_TMESSAGE_INCORRECT_TIME_STAMP_CREATE)};
except on E: Exception do
raise EClass.Create ([self,'_SetTimeStampCreate',ERR_TMESSAGE_SET_TIME_STAMP_CREATE,E],
['{5AEF918D-857E-4127-8124-0999B547CB63}']);
end;
end;
Ⓐ свобода сопротивление солидарность
|
|
Вадим К (статус: Академик), 16 декабря 2010, 12:00 [#10]:
Цитата:
определять все свойства всех классов в базовом неправильно
логично.
посмотрел реализацию методов *TimeStampCreate
в методе SetTimeStampCreate try-except выглядит немного лишним. Маловероятно, что там будет ошибка - она скорее отловиться методом _SetTimeStampCreate
Если все методы так выглядят - это с ума сойти можно.
Посмотрел на это все. Есть такие ещё предложения.
попробовать сделать новый класс для одного свойства. Если методы чтения/записи свойств у "большого" объекта более менее однотипны (либо можно выделить несколько групп - для числа, для строки), то делаем объект свойство (или несколько таких объектов). И можно сделать объявления попроще.
И есть второй подход. Называется "генератор". Суть в том, что эти все методы очень похожи друг на друга, и проще написать программу, которая будет брать текстовый файл, в котором описана структура (а ещё красивее - прямо с базы структуру брать) и по ней генерировать все эти классы. Так поступают многие "фреймворки" для крутых систем. Более того, делфи позволяет (начиная с 2006 версии вроде) подключать свои компиляторы и преобразователи текста. То есть можно спокойно прям в делфи писать себе структуру, а прекомпилятор вызовет утилиту и преобразует все.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
mirt.steelwater (статус: Посетитель), 16 декабря 2010, 12:17 [#11]:
да, я думал над первым предложенным вариантом ранее - он имеет свои плюсы и минусы.
плюсы в том, что нет лишнего кода, есть только функциональный код - изначально именно так у меня и было написано. но при большом размере проекта (и проект теоретически должны улучшать под себя в дальнейшем совершенно незнакомые мне люди, с которыми я смогу общаться максимум на плохом английском) - очень запутанно будет, если не будет методов класса для явных преобразований свойств в поля и полей в свойства. т.е. сейчас мне вроде все понятно - вот время в БД у меня в unix-формате, текст в 16-ричке здесь, а здесь он зашифрован и опять же переведен в 16-ричку, потом я делаю все операции в обратном порядке при загрузке. но если кто-нибудь глянет в бд, увидит 16-ричку, попытается перевести в ASCII или UNICOD - ничего дельного у него не выйдет, т.к. оно зашифровано - и все, он будет долго думать и искать, пока не поймет, что оно шифровалось, будет искать какими ключами оно должно шифроваться и расшифровываться и т.п. -- вообщем нет однотипности в коде в таком случае.
второй вариант меня заинтересовал - не могли бы дать ссылки на что-то похожее?
Ⓐ свобода сопротивление солидарность
|
|
mirt.steelwater (статус: Посетитель), 16 декабря 2010, 13:17 [#13]:
спасибо
для дельфи вряди получится это реализовать - сделать ассоциативный список методов у класса можно, но код их должен либо подгружаться из библиотеки либо уже должен быть реализован.
можно, конечно, попробовать сделать что-то вроде:
TMetaMethod = function (anArgs: array of const) : LongWord;
TMetaObject = class
private
f_Methods: TList;
f_Properties: TList;
protected
function GetMethodOf (anIndex: String) : TMetaMethod;
procedure SetMethodOf (anIndex: String; aValue: TMetaMethod);
//...
public
Methods [anIndex: String]: TMetaMethod read GetMethodOf write SetMethodOf;
Properties [anIndex: String]: TMetaProperty read GetPropertyOf write SetPropertyOf;
end;
и хранить в f_Methods указатели на функции, потом их вызывать, добавлять те или иные - в зависимости от типа поля БД и т.п.
но это уж совсем как-то монстроподобно мне видится..
когда то я делал на PHP в таблицах хранил классы, свойства классов, методы классов и объектов, связь потомков и родителей и т.п.
но в дельфи это будет проблематично, вероятно
Ⓐ свобода сопротивление солидарность
|
|
Вадим К (статус: Академик), 16 декабря 2010, 13:23 [#14]:
В вышеприведенном коде есть фундаментальная ошибка проектирования - свойства и методы их обрабатывающие - разделены. Нужно делать одну сущность методы+свойство и один потом "массив".
Галочка "подтверждения прочтения" - вселенское зло.
|
|
mirt.steelwater (статус: Посетитель), 16 декабря 2010, 13:29 [#15]:
хм.. почему?
Ⓐ свобода сопротивление солидарность
|
|
Вадим К (статус: Академик), 16 декабря 2010, 13:32 [#16]:
потому что не нужно плодить сущности без необходимости.
А в целом - в будущем, где то случайно в один массив добавим, а в другой забудем и будет для одного свойства вызываться совсем другой метод. Получаем феерические ошибки
Галочка "подтверждения прочтения" - вселенское зло.
|
|
mirt.steelwater (статус: Посетитель), 16 декабря 2010, 13:39 [#17]:
ну я их думал по именам связывать как-то
а вообще можно, конечно, объявить свойство вроде такого:
TMetaProperty = packed record
Name: String;
Type: Integer; { TVarRec.VType values }
Value: TVarRec;
Default: TVarRec;
Get: TMetaMethod;
Set: TMetaMethod;
end;
тогда можно и в одном массиве хранить - только нужно будет хранить указатель на структуру и как-то их различать..
Ⓐ свобода сопротивление солидарность
|
|
Вадим К (статус: Академик), 16 декабря 2010, 13:49 [#18]:
это уже реальнее идея. И она сильно похожа на то, что я предлагал. Нужен один базовый класс, а для различных типов данных заводим наследников. Суммарно их вряд ли более 10 будет. И работа пойдет быстрее.
packed тут не нужно. памяти он сильно не уменьшит. а в целом обычно он сказывается на производительности.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
mirt.steelwater (статус: Посетитель), 16 декабря 2010, 14:00 [#19]:
спасибо
попробую переделать это в таком варианте
Ⓐ свобода сопротивление солидарность
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|