![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Наследники TList
Добежал © (2008-09-24 18:19:00)Думаю, в любом крупном проекте используется TList, так как постоянно возникает необходимость хранить списки с некоей информацией. И тут возможны два подхода:
1) когда о содержимом TList знает только "вышестоящий" класс, он и типизирует информацию:
TMySuperClass = class(...)
...
FClientList: TList;
...
end;
Реализация:
constructor TMySuperClass.create;
begin
...
FClientList := TList.Create;
...
end;
destructor TMySuperClass.destroy;
var
i: integer;
begin
...
for i:=0 to FClientList.Count - 1 do
Dispose(PClientInfo(FClientList[i]));
FClientList.Free;
end;
Можно немного продвинутей писать (продвинутей ли?), если в классе происходит удаление какого-то клиента во время работы, то ввести функцию DeleteClientByPos:
function DeleteClientByPOS(iPos: integer): boolean;
begin
if (iPos >=0) and (iPos < FClientList.Count) then
begin
Dispose(FClientList[iPos]);
FClientList.delete(iPos);
Result := true;
end
else Result := false;
end;
Тогда деструктор поменять можно на:
for i:=FClientList.Count-1 downto 0 do
DeleteClientByPOS(i);
суть не меняется.
2) второй же вариант - это написание каждый раз наследника TList, который будет уметь работать именно с типизированными указателями нужной структуры.
Второй вариант по идеологии правильней, но каждый раз писать... А ведь таких списков может быть десятки, сотни... тысячи. Да и шаблоны дельфи не поддерживает.
Кто как делает? Еще фишка в том, что половина модуля может состоять потом из реализаций TList'ов. Выносить в отдельный модуль uData? Или uLister какой-нибудь ;)
А наверняка еще и парадигма мож какая имеется на эту тему? Жду отзывов кто как делает ;)
Поросенок Винни-Пух (2008-09-26 12:59:00) [41]project->import type library->microsoft xml,v4.0 /6.0 ->create unit
Ins (2008-09-26 12:56:00) [42]Если версия Delphi от 2005 до 2007, то можно использовать что-то подобное такому Code Template, облегчающему написание потомков от TList/TObjectList:
<?xml version="1.0" encoding="utf-8" ?>
<codetemplate xmlns=" http://schemas.borland.com/Delphi/2005/codetemplates" version="1.0.0">
<template name="SafeObjectList" invoke="manual">
<description>
Safe type TObjectList
</description>
<author>
Ins
</author>
<point name="listclass">
<text>
TMyObjectList
</text>
<hint>
List class name
</hint>
</point>
<point name="itemclass">
<text>
TMyObject
</text>
<hint>
Item class name
</hint>
</point>
<code language="Delphi" delimiter="|"><![CDATA[|*||listclass| = class(TObjectList)
|*|protected
|*||*|function GetItem(Index: Integer): |itemclass|;
|*||*|procedure SetItem(Index: Integer; const Value: |itemclass|);
|*|public
|*||*|function Add(AObject: |itemclass|): Integer;
|*||*|function Extract(Item: |itemclass|): |itemclass|;
|*||*|function Remove(AObject: |itemclass|): Integer;
|*||*|function IndexOf(AObject: |itemclass|): Integer;
|*||*|procedure Insert(Index: Integer; AObject: |itemclass|);
|*||*|function First: |itemclass|;
|*||*|function Last: |itemclass|;
|*||*|property Items[Index: Integer]: |itemclass| read GetItem write SetItem; default;
|*|end;
{ |listclass| }
function |listclass|.Add(AObject: |itemclass|): Integer;
begin
|*|Result := inherited Add(AObject);
end;
function |listclass|.Extract(Item: |itemclass|): |itemclass|;
begin
|*|Result := |itemclass|(inherited Extract(Item));
end;
function |listclass|.First: |itemclass|;
begin
|*|Result := |itemclass|(inherited First);
end;
function |listclass|.GetItem(Index: Integer): |itemclass|;
begin
|*|Result := |itemclass|(inherited Items[Index]);
end;
function |listclass|.IndexOf(AObject: |itemclass|): Integer;
begin
|*|Result := inherited IndexOf(AObject);
end;
procedure |listclass|.Insert(Index: Integer; AObject: |itemclass|);
begin
|*|inherited Insert(Index, AObject);
end;
function |listclass|.Last: |itemclass|;
begin
|*|Result := |itemclass|(inherited Last);
end;
function |listclass|.Remove(AObject: |itemclass|): Integer;
begin
|*|Result := inherited Remove(AObject);
end;
procedure |listclass|.SetItem(Index: Integer; const Value: |itemclass|);
begin
|*|inherited Items[Index] := Value;
end;]]>
</template>
</codetemplate>
Добежал (2008-09-26 12:50:00) [43]Поросенок Винни-Пух, а какие средства используешь для работы с XML? Что-то дельфовое или стороннее?
WinApi?
Поросенок Винни-Пух (2008-09-26 10:50:00) [44]вот поэтому-то я как-то и решил, что ну его в баню.
заменил лист на ixmdonnodelist а рекорд на ixmldomnode
при этом структуры разные, а типов всего два на все про все.
Ega23 (2008-09-26 10:45:00) [45]
> Ега, ты лучше автору расскажи как ему его листы с множественными
> типами рекордов пополиморфеестее обрабатывать и поинкапсулеестее
> проектировать.
А никак. Если рекорд - то я вообще не вижу сильно большого смысла TList перекрывать. Ну разве Notify, чтобы удалялось по Clear.
Тысячи различных рекордов? Ну пусть, рекоды-же он описывает? почему там же и лист не описать?
Хотя да, в данной ситуации без шаблонов тяжеловато - многа букаф получаецца.
Медвежонок Пятачок (2008-09-25 23:19:00) [46]Ега, ты лучше автору расскажи как ему его листы с множественными типами рекордов пополиморфеестее обрабатывать и поинкапсулеестее проектировать.
Скоро полсотни постов, а у него все еще оргазм не наступил.
Обжект лист и объекты для чисто тупо под контейнер полей использовать - так я тоже начну песню петь про тяжести и избыточности.
Ega23 (2008-09-25 23:13:00) [47]
> Медвежонок Пятачок © (25.09.08 22:26) [47]
ну и че? Ну нормальное и вполне разумное применение xml.
А вот когда пишешь, ну не знаю, очередь какую-нибудь, причем не простую FIFO, а похитрее - что, тоже XML надо использовать?
Проблема его в том, что это, как ни крути - суть строка. Да, можно дополнительно извернуться и написать такой парсер, который потом в нодах будет хранить именно те типы данных, которые требуются. Но в целом - строка, как ни крути. И ты, как человек весьма не плохо разбирающийся в БД, прекрасно знаешь, что такое "сравнение по строке" vs "сравнение по числу".
Всякой технологии должно быть своё место. Фомировать XML при передачи метаданных там, где он не нужен - не стоит. Там где он будет вполне уместен - почему бы и нет (с учетом того, что сейчас практически все СУБД такой тип данных имеют. Ну, не экзотические, во всяком случае).
Малой саперной лопаткой, к примеру, можно не только копать. Её можно вполне сносно в цель метать. Мы ей и консервы открывали, и дрова рубили и хлеб даже как-то резали. Но буть уверен, что если ьы в тот момент был топор - дрова рубили бы топором. :)
Медвежонок Пятачок (2008-09-25 22:26:00) [48]> особенно бинарные данные там хорошо будут смотреться особенно
> в плане скорости добавления/удаления
Рассказываю про бинарные данные.
Есть у меня дистрибутив программы. Коробочная штука. После инсталла полностью готова к работе. Кроме одной вещи, которую в инсталл не засунешь. Это контейнеры приватных ключей и хранилище сертификатов.
Для каждого нового клиента генерируется свой комплект.
При создании учетки для нового клиента создается xml документ куда кроме прочих параметров, используемых при инициализации чистой бд добавляются те самые ключи и сертификаты в b64 виде в узлах cdata.
Объемы разумеется не гигабайтные, но никаих проблем со скоростью никто не имеет. Одни сплошные удобства. При запуске с параметрами все данные переезжают в бд, все файлы декодируются из xml и ложаться куда надо.
guav (2008-09-25 22:16:00) [49]> [44] Медвежонок Пятачок © (25.09.08 22:08)
Зачем вообще циклы ? Надо что-то сделать с кучей рекордов ? Ну если входные данные в XML и выходные в XML, не круче ли будет написать XSL ?
DVM (2008-09-25 22:11:00) [50]
> А зачем всюду пихать циклы for/while и иф/елс?
но ими же не пытаются заменить XML :)
Медвежонок Пятачок (2008-09-25 22:08:00) [51]Я действительно не понимаю зачем пихать всюду XML
А зачем всюду пихать циклы for/while и иф/елс?
Типа тоже вопрос.
Медвежонок Пятачок (2008-09-25 22:05:00) [52]Я действительно не понимаю зачем пихать всюду XML
Многие многого не понимают.
Я вот не понимаю проблем автора ветки.
guav (2008-09-25 22:02:00) [53]> Речь идет не о конкретной разработке, а вообще о подходах...
подходы бывают разные.
1. array of TRecord.
2. TList как есть. А лучше сделать классами и TObjectList, тоже как есть.
3. Написать генерилку и нагенерячить.
http://www.torry.ru/authorsmore.php?id=1994
4. Связный список. Кстати, в WinAPI есть lock-free реализация односвязного списка.
5. Частичная иммитация С++овской STL тоже возможна
http://sourceforge.net/projects/dclx
6. Convert absolutely everything to XML
http://www.bitschubser.com/HowToRTFM/Q209354%20-%20HOWTO.htm
...
Ega23 (2008-09-25 21:36:00) [54]Ну человек - фанат хмл. Я вот Sepultura люблю, он - хмл.
DVM (2008-09-25 21:19:00) [55]
> Ничего ты не понимаешь.
Я действительно не понимаю зачем пихать всюду XML, заменяя им все и вся и пытаясь прикрутить его вместо удобных и проверенных временем вещей.
Ega23 (2008-09-25 21:12:00) [56]
> особенно бинарные данные там хорошо будут смотреться особенно
> в плане скорости добавления/удаления
Зато это не ini-файлы и xPath есть.
Ничего ты не понимаешь.
DVM (2008-09-25 21:08:00) [57]
> Что я загоню все в xml, что вы насоздаете все сто тысяч
> экземпляров рекордов.
особенно бинарные данные там хорошо будут смотреться особенно в плане скорости добавления/удаления
Sapersky (2008-09-25 19:49:00) [58]Еще вариант - использовать GetMem/FreeMem, а у списка сдалать свойство ItemSize. Хотя для record'ов лучше массив.
Можно сделать универсальный список/массив и с New/Dispose (точнее, system._Initialize/_Finalize), будет поддержка длинных строк и прочих автоматически финализируемых элементов в записях.
Поросенок Винни-Пух (2008-09-25 17:28:00) [59]если бы тот ЯП был
В некотором смысле он и есть яп.
особенно xsl
Поросенок Винни-Пух (2008-09-25 17:25:00) [60]Во всех других случаях это совершенно неподходящее решение.
да не надо ля-ля.
Ну есть сто тысяч элементов списка по тридцать три поля.
Что я загоню все в xml, что вы насоздаете все сто тысяч экземпляров рекордов.