![]() |
| ||
|
|
Новости |
Поиск |
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 какой-нибудь ;)
А наверняка еще и парадигма мож какая имеется на эту тему? Жду отзывов кто как делает ;)
KSergey (2008-09-25 17:19:00) [61]> Поросенок Винни-Пух © (25.09.08 12:15) [27]
> берешь xml документ.
Это все прикольно, когда вообще нет требований по скорости, да и по объему не особо. Зато надо визуализировать/редактировать/серилизовать (ёпрс! всегда любил это слово за возможность описки)
Во всех других случаях это совершенно неподходящее решение.
Поросенок Винни-Пух (2008-09-25 17:02:00) [62]не могу придумать пример, не зная всех прелестей технологии.
прелести я покажу, но нужен пример. у меня их своих конечно куча, но доходчивей будет если, задача будет не моя.
Ega23 (2008-09-25 16:55:00) [63]
> выглядит привлекательно, но я не понял. Можно пример?
Не надо, он фанат xml. Он бы на самом xml всё писал, если бы тот ЯП был.
Добежал (2008-09-25 16:50:00) [64]
> Для примера нужен пример задачи
не могу придумать пример, не зная всех прелестей технологии. Наверное, тебе легче составить пример задачи, реализация которой во всей красе выявит гибкость подхода.
Поросенок Винни-Пух (2008-09-25 14:09:00) [65]Для примера нужен пример задачи
Добежал (2008-09-25 12:53:00) [66]
> берешь xml документ.
> придумывешь иерархию узлов для хранения своих многочисленных
> структур.
> создаешь один раз на всю оставшуюся жизнь несколько библиотечных
> функций для извлечения данных.
> все.
>
> доспуп к данным превращается из императивного в декларативный.
>
> удобно хранить, просто сериализировать, легко визуализировать
> и редактировать. гибкость просто на высоте.
>
> никаких многочисленных TMyRecord = record end;
> никаких тысяч и тысяч строк рутинного кода каждый раз когда
> нужна новая структура.
выглядит привлекательно, но я не понял. Можно пример?
to guav, не могу тебе ответить на твои вопросы. Речь идет не о конкретной разработке, а вообще о подходах...
guav (2008-09-25 12:42:00) [67]Что вообще нужно от контейнера ?
Удаление из середины вообще нужно ?
А констатное время доступа к элементу по его номеру в списке ?
Нужен ли полиморфизм (подозреваю что нет, т.к. речь о рекордах) ?
Нужна ли сортировка ?
Поросенок Винни-Пух (2008-09-25 12:15:00) [68]берешь xml документ.
придумывешь иерархию узлов для хранения своих многочисленных структур.
создаешь один раз на всю оставшуюся жизнь несколько библиотечных функций для извлечения данных.
все.
доспуп к данным превращается из императивного в декларативный.
удобно хранить, просто сериализировать, легко визуализировать и редактировать. гибкость просто на высоте.
никаких многочисленных TMyRecord = record end;
никаких тысяч и тысяч строк рутинного кода каждый раз когда нужна новая структура.
Все есть, юзай-не хочу.
Не хочется обрабатывать на клиенте - отдал xml sql серверу и наоборот.
От возможностей глаза разбегаются.
Туча времени высвобождается на решение действительно творческих задач.
MsGuns (2008-09-25 11:38:00) [69]>Добежал (25.09.08 11:24) [23]
>А можно таки узнать, почему не нужно наследоваться от TList?
Потому же, почему не имеет смысл изобретать модификации зубила. Оно само по себе достаточно функционально, а если приспичило сверлить или закручивать гайки, то для этого имеются другие, более пригодные инструменты. О чем здесь Вам талдычат два десятка постов
Palladin (2008-09-25 11:35:00) [70]
> А можно таки узнать, почему не нужно наследоваться от TList?
ну не знаю как там другие, но, лично я, никогда не наследуюсь от TList и всегда создаю класс его агрегирующий, что позволяет всегда, прозрачно для программиста-клиента, заменить его на какой либо другой контейнер
Поросенок Винни-Пух (2008-09-25 11:31:00) [71]потому что рано или поздно начинаешь задаваться над вопросом:
"а зачем мне постоянно убивать время на поддержку многочисленных классов рекордов, что нет занятий более интересных, чем эта рутина?"
Добежал (2008-09-25 11:24:00) [72]
> Почему не нужно наследоваться от TList написано у Бакнела.
> У меня нет доводов которые я могу ему противопоставить
эээ... TList специально сделан, чтобы от него удобно было наследоваться по идее то...
А можно таки узнать, почему не нужно наследоваться от TList?
Медвежонок Пятачок (2008-09-25 08:09:00) [73]я отказался от TList с рекордами вообще.
использую ixmldomdocument2.
сразу убивается целое стадо зайцев.
korneley (2008-09-25 06:33:00) [74]Я как-то не заморачивался, делал, типа:
TRange = class
ipStart,
ipEnd : TAddr;
Checked : boolean;
end;
TRangeList = class(TObjectList)
function GetItem(Index: Integer): TRange;
procedure SetItem(Index: Integer; AObject: TRange);
public
property Items[Index: Integer]: TRange read GetItem write SetItem; default;
end;
...
{ TRangeList }
function TRangeList.GetItem(Index: Integer): TRange;
begin
Result := TRange(inherited Items[Index]);
end;
procedure TRangeList.SetItem(Index: Integer; AObject: TRange);
begin
inherited Items[Index] := AObject;
end;
Ибо, что ещё "впихнуть" в рекорд (который вдруг становится классом) понадобится - не всегда заранее известно.
GrayFace (2008-09-25 05:09:00) [75]Еще вариант - использовать GetMem/FreeMem, а у списка сдалать свойство ItemSize. Хотя для record'ов лучше массив.
brother (2008-09-25 03:18:00) [76]> И чем раздражало?
Лишние телодвижения? ;)
Германн (2008-09-25 01:48:00) [77]
> Real © (25.09.08 01:43) [17]
>
>
> > Ага. А ещё в обработчики событий Sender приходит как TObject
>
> Согласен, раздражало(ет) это всегда
>
И чем раздражало?
Real (2008-09-25 01:43:00) [78]
> Ага. А ещё в обработчики событий Sender приходит как TObject
Согласен, раздражало(ет) это всегда
Германн (2008-09-25 01:21:00) [79]
> А ещё в обработчики событий Sender приходит как TObject,
> приводить его к нужному типу неудобно.
Устойчивая привычка проверять и приводить типы закладывается довольно быстро.
guav (2008-09-25 00:52:00) [80]> [14] Ega23 © (25.09.08 00:10)
> Напрямую не всегда удобно, приводить Items[i] всегда надо.
Ага. А ещё в обработчики событий Sender приходит как TObject, приводить его к нужному типу неудобно. В Делфи даункастинг - норма.